From 797b91a9fe825c41b58a9fbcedfbeaeab786211d Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Sun, 10 May 2020 13:35:01 +0100 Subject: [PATCH 001/229] r/aws_networkmanager_global_network: initial configuration --- aws/config.go | 3 + .../generators/servicetags/main.go | 1 + .../generators/updatetags/main.go | 1 + .../service_generation_customizations.go | 3 + aws/internal/keyvaluetags/service_tags_gen.go | 28 ++ aws/internal/keyvaluetags/update_tags_gen.go | 37 +++ aws/provider.go | 1 + ...ource_aws_networkmanager_global_network.go | 261 ++++++++++++++++++ 8 files changed, 335 insertions(+) create mode 100644 aws/resource_aws_networkmanager_global_network.go diff --git a/aws/config.go b/aws/config.go index 0348e71e5d0..fcdc8c6fc2a 100644 --- a/aws/config.go +++ b/aws/config.go @@ -105,6 +105,7 @@ import ( "github.com/aws/aws-sdk-go/service/mediastoredata" "github.com/aws/aws-sdk-go/service/mq" "github.com/aws/aws-sdk-go/service/neptune" + "github.com/aws/aws-sdk-go/service/networkmanager" "github.com/aws/aws-sdk-go/service/opsworks" "github.com/aws/aws-sdk-go/service/organizations" "github.com/aws/aws-sdk-go/service/personalize" @@ -283,6 +284,7 @@ type AWSClient struct { mediastoredataconn *mediastoredata.MediaStoreData mqconn *mq.MQ neptuneconn *neptune.Neptune + networkmanagerconn *networkmanager.NetworkManager opsworksconn *opsworks.OpsWorks organizationsconn *organizations.Organizations partition string @@ -500,6 +502,7 @@ func (c *Config) Client() (interface{}, error) { mediastoredataconn: mediastoredata.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["mediastoredata"])})), mqconn: mq.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["mq"])})), neptuneconn: neptune.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["neptune"])})), + networkmanagerconn: networkmanager.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["networkmanager"])})), opsworksconn: opsworks.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["opsworks"])})), organizationsconn: organizations.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints["organizations"])})), partition: partition, diff --git a/aws/internal/keyvaluetags/generators/servicetags/main.go b/aws/internal/keyvaluetags/generators/servicetags/main.go index 4382879b7a0..79a7a1743bb 100644 --- a/aws/internal/keyvaluetags/generators/servicetags/main.go +++ b/aws/internal/keyvaluetags/generators/servicetags/main.go @@ -71,6 +71,7 @@ var sliceServiceNames = []string{ "lightsail", "mediastore", "neptune", + "networkmanager", "organizations", "quicksight", "ram", diff --git a/aws/internal/keyvaluetags/generators/updatetags/main.go b/aws/internal/keyvaluetags/generators/updatetags/main.go index ee18203bf73..628f8ee646a 100644 --- a/aws/internal/keyvaluetags/generators/updatetags/main.go +++ b/aws/internal/keyvaluetags/generators/updatetags/main.go @@ -92,6 +92,7 @@ var serviceNames = []string{ "mediastore", "mq", "neptune", + "networkmanager", "opsworks", "organizations", "pinpoint", diff --git a/aws/internal/keyvaluetags/service_generation_customizations.go b/aws/internal/keyvaluetags/service_generation_customizations.go index 071ce0d9b5b..9d9eb2e10a3 100644 --- a/aws/internal/keyvaluetags/service_generation_customizations.go +++ b/aws/internal/keyvaluetags/service_generation_customizations.go @@ -82,6 +82,7 @@ import ( "github.com/aws/aws-sdk-go/service/mediastore" "github.com/aws/aws-sdk-go/service/mq" "github.com/aws/aws-sdk-go/service/neptune" + "github.com/aws/aws-sdk-go/service/networkmanager" "github.com/aws/aws-sdk-go/service/opsworks" "github.com/aws/aws-sdk-go/service/organizations" "github.com/aws/aws-sdk-go/service/pinpoint" @@ -268,6 +269,8 @@ func ServiceClientType(serviceName string) string { funcType = reflect.TypeOf(mq.New) case "neptune": funcType = reflect.TypeOf(neptune.New) + case "networkmanager": + funcType = reflect.TypeOf(networkmanager.New) case "opsworks": funcType = reflect.TypeOf(opsworks.New) case "organizations": diff --git a/aws/internal/keyvaluetags/service_tags_gen.go b/aws/internal/keyvaluetags/service_tags_gen.go index d39d83a52b7..643fd0fc7c3 100644 --- a/aws/internal/keyvaluetags/service_tags_gen.go +++ b/aws/internal/keyvaluetags/service_tags_gen.go @@ -56,6 +56,7 @@ import ( "github.com/aws/aws-sdk-go/service/lightsail" "github.com/aws/aws-sdk-go/service/mediastore" "github.com/aws/aws-sdk-go/service/neptune" + "github.com/aws/aws-sdk-go/service/networkmanager" "github.com/aws/aws-sdk-go/service/organizations" "github.com/aws/aws-sdk-go/service/quicksight" "github.com/aws/aws-sdk-go/service/ram" @@ -1852,6 +1853,33 @@ func NeptuneKeyValueTags(tags []*neptune.Tag) KeyValueTags { return New(m) } +// NetworkmanagerTags returns networkmanager service tags. +func (tags KeyValueTags) NetworkmanagerTags() []*networkmanager.Tag { + result := make([]*networkmanager.Tag, 0, len(tags)) + + for k, v := range tags.Map() { + tag := &networkmanager.Tag{ + Key: aws.String(k), + Value: aws.String(v), + } + + result = append(result, tag) + } + + return result +} + +// NetworkmanagerKeyValueTags creates KeyValueTags from networkmanager service tags. +func NetworkmanagerKeyValueTags(tags []*networkmanager.Tag) KeyValueTags { + m := make(map[string]*string, len(tags)) + + for _, tag := range tags { + m[aws.StringValue(tag.Key)] = tag.Value + } + + return New(m) +} + // OrganizationsTags returns organizations service tags. func (tags KeyValueTags) OrganizationsTags() []*organizations.Tag { result := make([]*organizations.Tag, 0, len(tags)) diff --git a/aws/internal/keyvaluetags/update_tags_gen.go b/aws/internal/keyvaluetags/update_tags_gen.go index ce0a1715fdc..68dc42f29ff 100644 --- a/aws/internal/keyvaluetags/update_tags_gen.go +++ b/aws/internal/keyvaluetags/update_tags_gen.go @@ -81,6 +81,7 @@ import ( "github.com/aws/aws-sdk-go/service/mediastore" "github.com/aws/aws-sdk-go/service/mq" "github.com/aws/aws-sdk-go/service/neptune" + "github.com/aws/aws-sdk-go/service/networkmanager" "github.com/aws/aws-sdk-go/service/opsworks" "github.com/aws/aws-sdk-go/service/organizations" "github.com/aws/aws-sdk-go/service/pinpoint" @@ -2811,6 +2812,42 @@ func NeptuneUpdateTags(conn *neptune.Neptune, identifier string, oldTagsMap inte return nil } +// NetworkmanagerUpdateTags updates networkmanager service tags. +// The identifier is typically the Amazon Resource Name (ARN), although +// it may also be a different identifier depending on the service. +func NetworkmanagerUpdateTags(conn *networkmanager.NetworkManager, identifier string, oldTagsMap interface{}, newTagsMap interface{}) error { + oldTags := New(oldTagsMap) + newTags := New(newTagsMap) + + if removedTags := oldTags.Removed(newTags); len(removedTags) > 0 { + input := &networkmanager.UntagResourceInput{ + ResourceArn: aws.String(identifier), + TagKeys: aws.StringSlice(removedTags.IgnoreAws().Keys()), + } + + _, err := conn.UntagResource(input) + + if err != nil { + return fmt.Errorf("error untagging resource (%s): %w", identifier, err) + } + } + + if updatedTags := oldTags.Updated(newTags); len(updatedTags) > 0 { + input := &networkmanager.TagResourceInput{ + ResourceArn: aws.String(identifier), + Tags: updatedTags.IgnoreAws().NetworkmanagerTags(), + } + + _, err := conn.TagResource(input) + + if err != nil { + return fmt.Errorf("error tagging resource (%s): %w", identifier, err) + } + } + + return nil +} + // OpsworksUpdateTags updates opsworks service tags. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. diff --git a/aws/provider.go b/aws/provider.go index 0ca59302ae3..6528ce4b336 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -696,6 +696,7 @@ func Provider() terraform.ResourceProvider { "aws_network_acl_rule": resourceAwsNetworkAclRule(), "aws_network_interface": resourceAwsNetworkInterface(), "aws_network_interface_attachment": resourceAwsNetworkInterfaceAttachment(), + "aws_networkmanager_global_network": resourceAwsNetworkManagerGlobalNetwork(), "aws_opsworks_application": resourceAwsOpsworksApplication(), "aws_opsworks_stack": resourceAwsOpsworksStack(), "aws_opsworks_java_app_layer": resourceAwsOpsworksJavaAppLayer(), diff --git a/aws/resource_aws_networkmanager_global_network.go b/aws/resource_aws_networkmanager_global_network.go new file mode 100644 index 00000000000..e96cf138f4b --- /dev/null +++ b/aws/resource_aws_networkmanager_global_network.go @@ -0,0 +1,261 @@ +package aws + +import ( + "fmt" + "log" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" +) + +func resourceAwsNetworkManagerGlobalNetwork() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsNetworkManagerGlobalNetworkCreate, + Read: resourceAwsNetworkManagerGlobalNetworkRead, + Update: resourceAwsNetworkManagerGlobalNetworkUpdate, + Delete: resourceAwsNetworkManagerGlobalNetworkDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "tags": tagsSchema(), + }, + } +} + +func resourceAwsNetworkManagerGlobalNetworkCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + + input := &networkmanager.CreateGlobalNetworkInput{ + Description: aws.String(d.Get("description").(string)), + Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().NetworkmanagerTags(), + } + + if v, ok := d.GetOk("description"); ok { + input.Description = aws.String(v.(string)) + } + + log.Printf("[DEBUG] Creating Network Manager Global Network: %s", input) + output, err := conn.CreateGlobalNetwork(input) + if err != nil { + return fmt.Errorf("error creating Network Manager Global Network: %s", err) + } + + d.SetId(aws.StringValue(output.GlobalNetwork.GlobalNetworkId)) + + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.GlobalNetworkStatePending}, + Target: []string{networkmanager.CustomerGatewayAssociationStateAvailable}, + Refresh: networkmanagerGlobalNetworkRefreshFunc(conn, aws.StringValue(output.GlobalNetwork.GlobalNetworkId)), + Timeout: 10 * time.Minute, + } + + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf("error waiting for networkmanager Global Network (%s) availability: %s", d.Id(), err) + } + + return resourceAwsNetworkManagerGlobalNetworkRead(d, meta) +} + +func resourceAwsNetworkManagerGlobalNetworkRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + + globalNetwork, err := networkmanagerDescribeGlobalNetwork(conn, d.Id()) + + if isAWSErr(err, "InvalidGlobalNetworkID.NotFound", "") { + log.Printf("[WARN] networkmanager Global Network (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return fmt.Errorf("error reading networkmanager Global Network: %s", err) + } + + if globalNetwork == nil { + log.Printf("[WARN] networkmanager Global Network (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if aws.StringValue(globalNetwork.State) == networkmanager.GlobalNetworkStateDeleting { + log.Printf("[WARN] networkmanager Global Network (%s) in deleted state (%s), removing from state", d.Id(), aws.StringValue(globalNetwork.State)) + d.SetId("") + return nil + } + + d.Set("arn", globalNetwork.GlobalNetworkArn) + d.Set("description", globalNetwork.Description) + + if err := d.Set("tags", keyvaluetags.NetworkmanagerKeyValueTags(globalNetwork.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %s", err) + } + + return nil +} + +func resourceAwsNetworkManagerGlobalNetworkUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + + if d.HasChange("tags") { + o, n := d.GetChange("tags") + + if err := keyvaluetags.NetworkmanagerUpdateTags(conn, d.Id(), o, n); err != nil { + return fmt.Errorf("error updating networkmanager Global Network (%s) tags: %s", d.Id(), err) + } + } + + return nil +} + +func resourceAwsNetworkManagerGlobalNetworkDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + + input := &networkmanager.DeleteGlobalNetworkInput{ + GlobalNetworkId: aws.String(d.Id()), + } + + log.Printf("[DEBUG] Deleting networkmanager Global Network (%s): %s", d.Id(), input) + err := resource.Retry(2*time.Minute, func() *resource.RetryError { + _, err := conn.DeleteGlobalNetwork(input) + + if isAWSErr(err, "IncorrectState", "has non-deleted Transit Gateway Registrations") { + return resource.RetryableError(err) + } + + if isAWSErr(err, "IncorrectState", "has non-deleted Customer Gateway Associations") { + return resource.RetryableError(err) + } + + if isAWSErr(err, "IncorrectState", "has non-deleted Device") { + return resource.RetryableError(err) + } + + if isAWSErr(err, "IncorrectState", "has non-deleted Link") { + return resource.RetryableError(err) + } + + if isAWSErr(err, "IncorrectState", "has non-deleted Site") { + return resource.RetryableError(err) + } + + if err != nil { + return resource.NonRetryableError(err) + } + + return nil + }) + + if isResourceTimeoutError(err) { + _, err = conn.DeleteGlobalNetwork(input) + } + + if isAWSErr(err, "InvalidGlobalNetworkID.NotFound", "") { + return nil + } + + if err != nil { + return fmt.Errorf("error deleting networkmanager Global Network: %s", err) + } + + if err := waitForNetworkManagerGlobalNetworkDeletion(conn, d.Id()); err != nil { + return fmt.Errorf("error waiting for networkmanager Global Network (%s) deletion: %s", d.Id(), err) + } + + return nil +} + +func networkmanagerGlobalNetworkRefreshFunc(conn *networkmanager.NetworkManager, globalNetworkID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + globalNetwork, err := networkmanagerDescribeGlobalNetwork(conn, globalNetworkID) + + if isAWSErr(err, "InvalidGlobalNetworkID.NotFound", "") { + return nil, "DELETED", nil + } + + if err != nil { + return nil, "", fmt.Errorf("error reading NetworkManager Global Network (%s): %s", globalNetworkID, err) + } + + if globalNetwork == nil { + return nil, "DELETED", nil + } + + return globalNetwork, aws.StringValue(globalNetwork.State), nil + } +} + +func networkmanagerDescribeGlobalNetwork(conn *networkmanager.NetworkManager, globalNetworkID string) (*networkmanager.GlobalNetwork, error) { + input := &networkmanager.DescribeGlobalNetworksInput{ + GlobalNetworkIds: []*string{aws.String(globalNetworkID)}, + } + + log.Printf("[DEBUG] Reading NetworkManager Global Network (%s): %s", globalNetworkID, input) + for { + output, err := conn.DescribeGlobalNetworks(input) + + if err != nil { + return nil, err + } + + if output == nil || len(output.GlobalNetworks) == 0 { + return nil, nil + } + + for _, globalNetwork := range output.GlobalNetworks { + if globalNetwork == nil { + continue + } + + if aws.StringValue(globalNetwork.GlobalNetworkId) == globalNetworkID { + return globalNetwork, nil + } + } + + if aws.StringValue(output.NextToken) == "" { + break + } + + input.NextToken = output.NextToken + } + + return nil, nil +} + +func waitForNetworkManagerGlobalNetworkDeletion(conn *networkmanager.NetworkManager, globalNetworkID string) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{ + networkmanager.GlobalNetworkStateAvailable, + networkmanager.GlobalNetworkStateDeleting, + }, + Target: []string{""}, + Refresh: networkmanagerGlobalNetworkRefreshFunc(conn, globalNetworkID), + Timeout: 10 * time.Minute, + NotFoundChecks: 1, + } + + log.Printf("[DEBUG] Waiting for NetworkManager Transit Gateway (%s) deletion", globalNetworkID) + _, err := stateConf.WaitForState() + + if isResourceNotFoundError(err) { + return nil + } + + return err +} From e6f4892f04ca8beac46b1482ec6c9a9ea7c90f52 Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Sun, 10 May 2020 16:03:54 +0100 Subject: [PATCH 002/229] r/aws_networkmanager_global_network: initial tests --- ..._aws_networkmanager_global_network_test.go | 246 ++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 aws/resource_aws_networkmanager_global_network_test.go diff --git a/aws/resource_aws_networkmanager_global_network_test.go b/aws/resource_aws_networkmanager_global_network_test.go new file mode 100644 index 00000000000..5ad89e4c4db --- /dev/null +++ b/aws/resource_aws_networkmanager_global_network_test.go @@ -0,0 +1,246 @@ +package aws + +import ( + "fmt" + "log" + "regexp" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func init() { + resource.AddTestSweepers("aws_networkmanager_global_network", &resource.Sweeper{ + Name: "aws_networkmanager_global_network", + F: testSweepNetworkManagerGlobalNetwork, + }) +} + +func testSweepNetworkManagerGlobalNetwork(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*AWSClient).networkmanagerconn + input := &networkmanager.DescribeGlobalNetworksInput{} + var sweeperErrs *multierror.Error + + err = conn.DescribeGlobalNetworksPages(input, + func(page *networkmanager.DescribeGlobalNetworksOutput, lastPage bool) bool { + for _, globalNetwork := range page.GlobalNetworks { + input := &networkmanager.DeleteGlobalNetworkInput{ + GlobalNetworkId: globalNetwork.GlobalNetworkId, + } + id := aws.StringValue(globalNetwork.GlobalNetworkId) + + log.Printf("[INFO] Deleting Network Manager Global Network: %s", id) + _, err := conn.DeleteGlobalNetwork(input) + + if isAWSErr(err, "InvalidGlobalNetworkID.NotFound", "") { + continue + } + + if err != nil { + sweeperErr := fmt.Errorf("failed to delete Network Manager Global Network %s: %s", id, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + + if err := waitForNetworkManagerGlobalNetworkDeletion(conn, id); err != nil { + sweeperErr := fmt.Errorf("error waiting for Network Manager Global Network (%s) deletion: %s", id, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + return !lastPage + }) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping Network Manager Global Network sweep for %s: %s", region, err) + return nil + } + + if err != nil { + return fmt.Errorf("Error retrieving Network Manager Global Networks: %s", err) + } + + return sweeperErrs.ErrorOrNil() +} + +func TestAccAWSNetworkManagerGlobalNetwork_basic(t *testing.T) { + resourceName := "aws_networkmanager_global_network.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsNetworkManagerGlobalNetworkDestroy, + Steps: []resource.TestStep{ + { + Config: testAccNetworkManagerGlobalNetworkConfig("test"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerGlobalNetworkExists(resourceName), + testAccMatchResourceAttrGlobalARN(resourceName, "arn", "networkmanager", regexp.MustCompile(`global-network/global-network-.+`)), + resource.TestCheckResourceAttr(resourceName, "description", "test"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccNetworkManagerGlobalNetworkConfig_Update("test updated"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerGlobalNetworkExists(resourceName), + testAccMatchResourceAttrGlobalARN(resourceName, "arn", "networkmanager", regexp.MustCompile(`global-network/global-network-.+`)), + resource.TestCheckResourceAttr(resourceName, "description", "test updated"), + ), + }, + }, + }) +} + +func TestAccAWSNetworkManagerGlobalNetwork_tags(t *testing.T) { + resourceName := "aws_networkmanager_global_network.test" + description := "test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsNetworkManagerGlobalNetworkDestroy, + Steps: []resource.TestStep{ + { + Config: testAccNetworkManagerGlobalNetworkConfigTags1(description, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerGlobalNetworkExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "test"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccNetworkManagerGlobalNetworkConfigTags2(description, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerGlobalNetworkExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "test"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccNetworkManagerGlobalNetworkConfigTags1(description, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerGlobalNetworkExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "test"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + }, + }) +} + +func testAccCheckAwsNetworkManagerGlobalNetworkDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_networkmanager_global_network" { + continue + } + + globalNetwork, err := networkmanagerDescribeGlobalNetwork(conn, rs.Primary.ID) + if err != nil { + if isAWSErr(err, networkmanager.ErrCodeResourceNotFoundException, "") { + return nil + } + return err + } + + if globalNetwork == nil { + continue + } + + return fmt.Errorf("Expected Global Network to be destroyed, %s found", rs.Primary.ID) + } + + return nil +} + +func testAccCheckAwsNetworkManagerGlobalNetworkExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn + + globalNetwork, err := networkmanagerDescribeGlobalNetwork(conn, rs.Primary.ID) + + if err != nil { + return err + } + + if globalNetwork == nil { + return fmt.Errorf("Network Manager Global Network not found") + } + + if aws.StringValue(globalNetwork.State) != networkmanager.GlobalNetworkStateAvailable && aws.StringValue(globalNetwork.State) != networkmanager.GlobalNetworkStatePending { + return fmt.Errorf("Network Manager Global Network (%s) exists in (%s) state", rs.Primary.ID, aws.StringValue(globalNetwork.State)) + } + + return err + } +} + +func testAccNetworkManagerGlobalNetworkConfig(description string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = %q +} +`, description) +} + +func testAccNetworkManagerGlobalNetworkConfigTags1(description, tagKey1, tagValue1 string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = %q + + tags = { + %q = %q + } +} +`, description, tagKey1, tagValue1) +} + +func testAccNetworkManagerGlobalNetworkConfigTags2(description, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = %q + + tags = { + %q = %q + %q = %q + } +} +`, description, tagKey1, tagValue1, tagKey2, tagValue2) +} + +func testAccNetworkManagerGlobalNetworkConfig_Update(description string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = %q +} +`, description) +} From 6e93120c68b678e6a3a57c15ace0853f94bfd1ef Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Tue, 12 May 2020 17:49:00 +0100 Subject: [PATCH 003/229] r/aws_networkmanager_global_network: fix update tagging The identifier for calls to keyvaluetags.NetworkmanagerUpdateTags is the resource arn not the resource id output from acceptance tests: make testacc TEST=./aws TESTARGS='-run=TestAccAWSNetworkManagerGlobalNetwork' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSNetworkManagerGlobalNetwork -timeout 120m === RUN TestAccAWSNetworkManagerGlobalNetwork_basic === PAUSE TestAccAWSNetworkManagerGlobalNetwork_basic === RUN TestAccAWSNetworkManagerGlobalNetwork_tags === PAUSE TestAccAWSNetworkManagerGlobalNetwork_tags === CONT TestAccAWSNetworkManagerGlobalNetwork_basic === CONT TestAccAWSNetworkManagerGlobalNetwork_tags --- PASS: TestAccAWSNetworkManagerGlobalNetwork_basic (68.59s) --- PASS: TestAccAWSNetworkManagerGlobalNetwork_tags (90.29s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 91.320s also correct debug message --- aws/resource_aws_networkmanager_global_network.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_networkmanager_global_network.go b/aws/resource_aws_networkmanager_global_network.go index e96cf138f4b..577fe35015a 100644 --- a/aws/resource_aws_networkmanager_global_network.go +++ b/aws/resource_aws_networkmanager_global_network.go @@ -116,7 +116,7 @@ func resourceAwsNetworkManagerGlobalNetworkUpdate(d *schema.ResourceData, meta i if d.HasChange("tags") { o, n := d.GetChange("tags") - if err := keyvaluetags.NetworkmanagerUpdateTags(conn, d.Id(), o, n); err != nil { + if err := keyvaluetags.NetworkmanagerUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { return fmt.Errorf("error updating networkmanager Global Network (%s) tags: %s", d.Id(), err) } } @@ -250,7 +250,7 @@ func waitForNetworkManagerGlobalNetworkDeletion(conn *networkmanager.NetworkMana NotFoundChecks: 1, } - log.Printf("[DEBUG] Waiting for NetworkManager Transit Gateway (%s) deletion", globalNetworkID) + log.Printf("[DEBUG] Waiting for NetworkManager Global Network (%s) deletion", globalNetworkID) _, err := stateConf.WaitForState() if isResourceNotFoundError(err) { From 8d16473426de4e746cb0e63de2c1344e2f404e25 Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Sun, 10 May 2020 21:51:08 +0100 Subject: [PATCH 004/229] r/aws_networkmanager_site: initial configuration --- aws/resource_aws_networkmanager_site.go | 311 ++++++++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 aws/resource_aws_networkmanager_site.go diff --git a/aws/resource_aws_networkmanager_site.go b/aws/resource_aws_networkmanager_site.go new file mode 100644 index 00000000000..7fc765d5997 --- /dev/null +++ b/aws/resource_aws_networkmanager_site.go @@ -0,0 +1,311 @@ +package aws + +import ( + "fmt" + "log" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/arn" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" +) + +func resourceAwsNetworkManagerSite() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsNetworkManagerSiteCreate, + Read: resourceAwsNetworkManagerSiteRead, + Update: resourceAwsNetworkManagerSiteUpdate, + Delete: resourceAwsNetworkManagerSiteDelete, + Importer: &schema.ResourceImporter{ + State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + d.Set("arn", d.Id()) + + idErr := fmt.Errorf("Expected ID in format of arn:aws:networkmanager::ACCOUNTID:site/GLOBALNETWORKID/SITEID and provided: %s", d.Id()) + + resARN, err := arn.Parse(d.Id()) + if err != nil { + return nil, idErr + } + + identifiers := strings.TrimPrefix(resARN.Resource, "site/") + identifierParts := strings.Split(identifiers, "/") + if len(identifierParts) != 2 { + return nil, idErr + } + d.SetId(identifierParts[1]) + d.Set("global_network_id", identifierParts[0]) + + return []*schema.ResourceData{d}, nil + }, + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "global_network_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "location": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Optional: true, + }, + "latitude": { + Type: schema.TypeString, + Optional: true, + }, + "longitude": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "tags": tagsSchema(), + }, + } +} + +func resourceAwsNetworkManagerSiteCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + + input := &networkmanager.CreateSiteInput{ + Description: aws.String(d.Get("description").(string)), + GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), + Location: resourceAwsNetworkManagerSiteLocation(d), + Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().NetworkmanagerTags(), + } + + log.Printf("[DEBUG] Creating Network Manager Site: %s", input) + output, err := conn.CreateSite(input) + if err != nil { + return fmt.Errorf("error creating Network Manager Site: %s", err) + } + + d.SetId(aws.StringValue(output.Site.SiteId)) + d.Set("global_network_id", aws.StringValue(output.Site.GlobalNetworkId)) + + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.SiteStatePending}, + Target: []string{networkmanager.CustomerGatewayAssociationStateAvailable}, + Refresh: networkmanagerSiteRefreshFunc(conn, aws.StringValue(output.Site.GlobalNetworkId), aws.StringValue(output.Site.SiteId)), + Timeout: 10 * time.Minute, + } + + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf("error waiting for Network Manager Site (%s) availability: %s", d.Id(), err) + } + + return resourceAwsNetworkManagerSiteRead(d, meta) +} + +func resourceAwsNetworkManagerSiteRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + + site, err := networkmanagerDescribeSite(conn, d.Get("global_network_id").(string), d.Id()) + + if isAWSErr(err, "InvalidSiteID.NotFound", "") { + log.Printf("[WARN] Network Manager Site (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return fmt.Errorf("error reading Network Manager Site: %s", err) + } + + if site == nil { + log.Printf("[WARN] Network Manager Site (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if aws.StringValue(site.State) == networkmanager.SiteStateDeleting { + log.Printf("[WARN] Network Manager Site (%s) in deleted state (%s), removing from state", d.Id(), aws.StringValue(site.State)) + d.SetId("") + return nil + } + + d.Set("arn", site.SiteArn) + d.Set("description", site.Description) + d.Set("location", site.Location) + + if err := d.Set("tags", keyvaluetags.NetworkmanagerKeyValueTags(site.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %s", err) + } + + return nil +} + +func resourceAwsNetworkManagerSiteUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + + if d.HasChange("tags") { + o, n := d.GetChange("tags") + + if err := keyvaluetags.NetworkmanagerUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { + return fmt.Errorf("error updating Network Manager Site (%s) tags: %s", d.Id(), err) + } + } + + return nil +} + +func resourceAwsNetworkManagerSiteDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + + input := &networkmanager.DeleteSiteInput{ + GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), + SiteId: aws.String(d.Id()), + } + + log.Printf("[DEBUG] Deleting Network Manager Site (%s): %s", d.Id(), input) + err := resource.Retry(2*time.Minute, func() *resource.RetryError { + _, err := conn.DeleteSite(input) + + if isAWSErr(err, "IncorrectState", "has non-deleted Link Associations") { + return resource.RetryableError(err) + } + + if isAWSErr(err, "IncorrectState", "has non-deleted Device") { + return resource.RetryableError(err) + } + + if err != nil { + return resource.NonRetryableError(err) + } + + return nil + }) + + if isResourceTimeoutError(err) { + _, err = conn.DeleteSite(input) + } + + if isAWSErr(err, "InvalidSiteID.NotFound", "") { + return nil + } + + if err != nil { + return fmt.Errorf("error deleting Network Manager Site: %s", err) + } + + if err := waitForNetworkManagerSiteDeletion(conn, d.Get("global_network_id").(string), d.Id()); err != nil { + return fmt.Errorf("error waiting for Network Manager Site (%s) deletion: %s", d.Id(), err) + } + + return nil +} + +func resourceAwsNetworkManagerSiteLocation(d *schema.ResourceData) *networkmanager.Location { + count := d.Get("location.#").(int) + if count == 0 { + return nil + } + + return &networkmanager.Location{ + Address: aws.String(d.Get("location.0.address").(string)), + Latitude: aws.String(d.Get("location.0.latitude").(string)), + Longitude: aws.String(d.Get("location.0.longitude").(string)), + } +} + +func networkmanagerSiteRefreshFunc(conn *networkmanager.NetworkManager, globalNetworkID, siteID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + site, err := networkmanagerDescribeSite(conn, globalNetworkID, siteID) + + if isAWSErr(err, "InvalidSiteID.NotFound", "") { + return nil, "DELETED", nil + } + + if err != nil { + return nil, "", fmt.Errorf("error reading Network Manager Site (%s): %s", siteID, err) + } + + if site == nil { + return nil, "DELETED", nil + } + + return site, aws.StringValue(site.State), nil + } +} + +func networkmanagerDescribeSite(conn *networkmanager.NetworkManager, globalNetworkID, siteID string) (*networkmanager.Site, error) { + input := &networkmanager.GetSitesInput{ + GlobalNetworkId: aws.String(globalNetworkID), + SiteIds: []*string{aws.String(siteID)}, + } + + log.Printf("[DEBUG] Reading Network Manager Site (%s): %s", siteID, input) + for { + output, err := conn.GetSites(input) + + if err != nil { + return nil, err + } + + if output == nil || len(output.Sites) == 0 { + return nil, nil + } + + for _, site := range output.Sites { + if site == nil { + continue + } + + if aws.StringValue(site.SiteId) == siteID { + return site, nil + } + } + + if aws.StringValue(output.NextToken) == "" { + break + } + + input.NextToken = output.NextToken + } + + return nil, nil +} + +func waitForNetworkManagerSiteDeletion(conn *networkmanager.NetworkManager, globalNetworkID, siteID string) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{ + networkmanager.SiteStateAvailable, + networkmanager.SiteStateDeleting, + }, + Target: []string{""}, + Refresh: networkmanagerSiteRefreshFunc(conn, globalNetworkID, siteID), + Timeout: 10 * time.Minute, + NotFoundChecks: 1, + } + + log.Printf("[DEBUG] Waiting for Network Manager Site (%s) deletion", siteID) + _, err := stateConf.WaitForState() + + if isResourceNotFoundError(err) { + return nil + } + + return err +} From a2b0e66230bb1ac3caf74dd374b2f203d1070a40 Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Mon, 11 May 2020 13:55:07 +0100 Subject: [PATCH 005/229] r/aws_networkmanager_site: initial tests --- aws/resource_aws_networkmanager_site_test.go | 292 +++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 aws/resource_aws_networkmanager_site_test.go diff --git a/aws/resource_aws_networkmanager_site_test.go b/aws/resource_aws_networkmanager_site_test.go new file mode 100644 index 00000000000..8714ba63b50 --- /dev/null +++ b/aws/resource_aws_networkmanager_site_test.go @@ -0,0 +1,292 @@ +package aws + +import ( + "fmt" + "log" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func init() { + resource.AddTestSweepers("aws_networkmanager_site", &resource.Sweeper{ + Name: "aws_networkmanager_site", + F: testSweepNetworkManagerSite, + }) +} + +func testSweepNetworkManagerSite(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*AWSClient).networkmanagerconn + var sweeperErrs *multierror.Error + + err = conn.GetSitesPages(&networkmanager.GetSitesInput{}, + func(page *networkmanager.GetSitesOutput, lastPage bool) bool { + for _, site := range page.Sites { + input := &networkmanager.DeleteSiteInput{ + GlobalNetworkId: site.GlobalNetworkId, + SiteId: site.SiteId, + } + id := aws.StringValue(site.SiteId) + globalNetworkID := aws.StringValue(site.GlobalNetworkId) + + log.Printf("[INFO] Deleting Network Manager Site: %s", id) + _, err := conn.DeleteSite(input) + + if isAWSErr(err, "InvalidSiteID.NotFound", "") { + continue + } + + if err != nil { + sweeperErr := fmt.Errorf("failed to delete Network Manager Site %s: %s", id, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + + if err := waitForNetworkManagerSiteDeletion(conn, globalNetworkID, id); err != nil { + sweeperErr := fmt.Errorf("error waiting for Network Manager Site (%s) deletion: %s", id, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + return !lastPage + }) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping Network Manager Site sweep for %s: %s", region, err) + return nil + } + + if err != nil { + return fmt.Errorf("Error retrieving Network Manager Sites: %s", err) + } + + return sweeperErrs.ErrorOrNil() +} + +func TestAccAWSNetworkManagerSite_basic(t *testing.T) { + resourceName := "aws_networkmanager_site.test" + gloablNetworkResourceName := "aws_networkmanager_global_network.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsNetworkManagerSiteDestroy, + Steps: []resource.TestStep{ + { + Config: testAccNetworkManagerSiteConfig("test"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerSiteExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "description", "test"), + resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetworkResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "location.#", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccAWSNetworkManagerSiteImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, + { + Config: testAccNetworkManagerSiteConfig_Update("test updated", "18.0029784", "-76.7897987"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerSiteExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "description", "test updated"), + resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetworkResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "location.#", "1"), + resource.TestCheckResourceAttr(resourceName, "location.0.address", ""), + resource.TestCheckResourceAttr(resourceName, "location.0.latitude", "18.0029784"), + resource.TestCheckResourceAttr(resourceName, "location.0.longitude", "-76.7897987"), + ), + }, + }, + }) +} + +func TestAccAWSNetworkManagerSite_tags(t *testing.T) { + resourceName := "aws_networkmanager_site.test" + description := "test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsNetworkManagerSiteDestroy, + Steps: []resource.TestStep{ + { + Config: testAccNetworkManagerSiteConfigTags1(description, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerSiteExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "test"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccAWSNetworkManagerSiteImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, + { + Config: testAccNetworkManagerSiteConfigTags2(description, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerSiteExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "test"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccNetworkManagerSiteConfigTags1(description, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerSiteExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "test"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + }, + }) +} + +func testAccCheckAwsNetworkManagerSiteDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_networkmanager_site" { + continue + } + + site, err := networkmanagerDescribeSite(conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) + if err != nil { + if isAWSErr(err, networkmanager.ErrCodeValidationException, "") { + return nil + } + return err + } + + if site == nil { + continue + } + + return fmt.Errorf("Expected Site to be destroyed, %s found", rs.Primary.ID) + } + + return nil +} + +func testAccCheckAwsNetworkManagerSiteExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn + + site, err := networkmanagerDescribeSite(conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) + + if err != nil { + return err + } + + if site == nil { + return fmt.Errorf("Network Manager Site not found") + } + + if aws.StringValue(site.State) != networkmanager.SiteStateAvailable && aws.StringValue(site.State) != networkmanager.SiteStatePending { + return fmt.Errorf("Network Manager Site (%s) exists in (%s) state", rs.Primary.ID, aws.StringValue(site.State)) + } + + return err + } +} + +func testAccNetworkManagerSiteConfig(description string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = "test" +} + +resource "aws_networkmanager_site" "test" { + description = %q + global_network_id = "${aws_networkmanager_global_network.test.id}" +} +`, description) +} + +func testAccNetworkManagerSiteConfigTags1(description, tagKey1, tagValue1 string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = "test" +} + +resource "aws_networkmanager_site" "test" { + description = %q + global_network_id = "${aws_networkmanager_global_network.test.id}" + + tags = { + %q = %q + } +} +`, description, tagKey1, tagValue1) +} + +func testAccNetworkManagerSiteConfigTags2(description, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = "test" +} + +resource "aws_networkmanager_site" "test" { + description = %q + global_network_id = "${aws_networkmanager_global_network.test.id}" + + tags = { + %q = %q + %q = %q + } +} +`, description, tagKey1, tagValue1, tagKey2, tagValue2) +} + +func testAccNetworkManagerSiteConfig_Update(description, latitude, longitude string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = "test" +} + +resource "aws_networkmanager_site" "test" { + description = %q + global_network_id = "${aws_networkmanager_global_network.test.id}" + + location { + latitude = %q + longitude = %q + } +} +`, description, latitude, longitude) +} + +func testAccAWSNetworkManagerSiteImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("Not found: %s", resourceName) + } + + return rs.Primary.Attributes["arn"], nil + } +} From af8cc05656eb6c003b7ea078db79de34703920ff Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Wed, 13 May 2020 22:40:01 +0100 Subject: [PATCH 006/229] r/aws_networkmanager_*: fixtures --- aws/provider.go | 1 + aws/resource_aws_networkmanager_global_network.go | 2 +- aws/resource_aws_networkmanager_site.go | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/aws/provider.go b/aws/provider.go index 6528ce4b336..c696916ae79 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -697,6 +697,7 @@ func Provider() terraform.ResourceProvider { "aws_network_interface": resourceAwsNetworkInterface(), "aws_network_interface_attachment": resourceAwsNetworkInterfaceAttachment(), "aws_networkmanager_global_network": resourceAwsNetworkManagerGlobalNetwork(), + "aws_networkmanager_site": resourceAwsNetworkManagerSite(), "aws_opsworks_application": resourceAwsOpsworksApplication(), "aws_opsworks_stack": resourceAwsOpsworksStack(), "aws_opsworks_java_app_layer": resourceAwsOpsworksJavaAppLayer(), diff --git a/aws/resource_aws_networkmanager_global_network.go b/aws/resource_aws_networkmanager_global_network.go index 577fe35015a..380ae8e36fc 100644 --- a/aws/resource_aws_networkmanager_global_network.go +++ b/aws/resource_aws_networkmanager_global_network.go @@ -59,7 +59,7 @@ func resourceAwsNetworkManagerGlobalNetworkCreate(d *schema.ResourceData, meta i stateConf := &resource.StateChangeConf{ Pending: []string{networkmanager.GlobalNetworkStatePending}, - Target: []string{networkmanager.CustomerGatewayAssociationStateAvailable}, + Target: []string{networkmanager.GlobalNetworkStateAvailable}, Refresh: networkmanagerGlobalNetworkRefreshFunc(conn, aws.StringValue(output.GlobalNetwork.GlobalNetworkId)), Timeout: 10 * time.Minute, } diff --git a/aws/resource_aws_networkmanager_site.go b/aws/resource_aws_networkmanager_site.go index 7fc765d5997..af75fe5981c 100644 --- a/aws/resource_aws_networkmanager_site.go +++ b/aws/resource_aws_networkmanager_site.go @@ -105,7 +105,7 @@ func resourceAwsNetworkManagerSiteCreate(d *schema.ResourceData, meta interface{ stateConf := &resource.StateChangeConf{ Pending: []string{networkmanager.SiteStatePending}, - Target: []string{networkmanager.CustomerGatewayAssociationStateAvailable}, + Target: []string{networkmanager.SiteStateAvailable}, Refresh: networkmanagerSiteRefreshFunc(conn, aws.StringValue(output.Site.GlobalNetworkId), aws.StringValue(output.Site.SiteId)), Timeout: 10 * time.Minute, } From e86632742f3edef594e3894130bc78971b624027 Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Wed, 13 May 2020 22:13:01 +0100 Subject: [PATCH 007/229] r/aws_networkmanager_device: initial configuration --- aws/provider.go | 1 + aws/resource_aws_networkmanager_device.go | 341 ++++++++++++++++++++++ 2 files changed, 342 insertions(+) create mode 100644 aws/resource_aws_networkmanager_device.go diff --git a/aws/provider.go b/aws/provider.go index c696916ae79..dd472d0ab03 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -696,6 +696,7 @@ func Provider() terraform.ResourceProvider { "aws_network_acl_rule": resourceAwsNetworkAclRule(), "aws_network_interface": resourceAwsNetworkInterface(), "aws_network_interface_attachment": resourceAwsNetworkInterfaceAttachment(), + "aws_networkmanager_device": resourceAwsNetworkManagerDevice(), "aws_networkmanager_global_network": resourceAwsNetworkManagerGlobalNetwork(), "aws_networkmanager_site": resourceAwsNetworkManagerSite(), "aws_opsworks_application": resourceAwsOpsworksApplication(), diff --git a/aws/resource_aws_networkmanager_device.go b/aws/resource_aws_networkmanager_device.go new file mode 100644 index 00000000000..aea232261e1 --- /dev/null +++ b/aws/resource_aws_networkmanager_device.go @@ -0,0 +1,341 @@ +package aws + +import ( + "fmt" + "log" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/arn" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" +) + +func resourceAwsNetworkManagerDevice() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsNetworkManagerDeviceCreate, + Read: resourceAwsNetworkManagerDeviceRead, + Update: resourceAwsNetworkManagerDeviceUpdate, + Delete: resourceAwsNetworkManagerDeviceDelete, + Importer: &schema.ResourceImporter{ + State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + d.Set("arn", d.Id()) + + idErr := fmt.Errorf("Expected ID in format of arn:aws:networkmanager::ACCOUNTID:device/GLOBALNETWORKID/DEVICEID and provided: %s", d.Id()) + + resARN, err := arn.Parse(d.Id()) + if err != nil { + return nil, idErr + } + + identifiers := strings.TrimPrefix(resARN.Resource, "device/") + identifierParts := strings.Split(identifiers, "/") + if len(identifierParts) != 2 { + return nil, idErr + } + d.SetId(identifierParts[1]) + d.Set("global_network_id", identifierParts[0]) + + return []*schema.ResourceData{d}, nil + }, + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "global_network_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "location": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Optional: true, + }, + "latitude": { + Type: schema.TypeString, + Optional: true, + }, + "longitude": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "model": { + Type: schema.TypeString, + Optional: true, + }, + "serial_number": { + Type: schema.TypeString, + Optional: true, + }, + "site_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "tags": tagsSchema(), + "type": { + Type: schema.TypeString, + Optional: true, + }, + "vendor": { + Type: schema.TypeString, + Optional: true, + }, + }, + } +} + +func resourceAwsNetworkManagerDeviceCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + + input := &networkmanager.CreateDeviceInput{ + Description: aws.String(d.Get("description").(string)), + GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), + Location: resourceAwsNetworkManagerDeviceLocation(d), + Model: aws.String(d.Get("model").(string)), + SerialNumber: aws.String(d.Get("serial_number").(string)), + SiteId: aws.String(d.Get("site_id").(string)), + Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().NetworkmanagerTags(), + Type: aws.String(d.Get("type").(string)), + Vendor: aws.String(d.Get("vendor").(string)), + } + + log.Printf("[DEBUG] Creating Network Manager Device: %s", input) + + output, err := conn.CreateDevice(input) + if err != nil { + return fmt.Errorf("error creating Network Manager Device: %s", err) + } + + d.SetId(aws.StringValue(output.Device.DeviceId)) + + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.DeviceStatePending}, + Target: []string{networkmanager.DeviceStateAvailable}, + Refresh: networkmanagerDeviceRefreshFunc(conn, aws.StringValue(output.Device.GlobalNetworkId), aws.StringValue(output.Device.DeviceId)), + Timeout: 10 * time.Minute, + } + + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf("error waiting for Network Manager Device (%s) availability: %s", d.Id(), err) + } + + return resourceAwsNetworkManagerDeviceRead(d, meta) +} + +func resourceAwsNetworkManagerDeviceRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + + device, err := networkmanagerDescribeDevice(conn, d.Get("global_network_id").(string), d.Id()) + + if isAWSErr(err, "InvalidDeviceID.NotFound", "") { + log.Printf("[WARN] Network Manager Device (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return fmt.Errorf("error reading Network Manager Device: %s", err) + } + + if device == nil { + log.Printf("[WARN] Network Manager Device (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if aws.StringValue(device.State) == networkmanager.DeviceStateDeleting { + log.Printf("[WARN] Network Manager Device (%s) in deleted state (%s), removing from state", d.Id(), aws.StringValue(device.State)) + d.SetId("") + return nil + } + + d.Set("arn", device.DeviceArn) + d.Set("description", device.Description) + d.Set("location", device.Location) + d.Set("model", device.Model) + d.Set("serial_number", device.SerialNumber) + d.Set("site_id", device.SiteId) + d.Set("type", device.Type) + d.Set("vendor", device.Vendor) + + if err := d.Set("tags", keyvaluetags.NetworkmanagerKeyValueTags(device.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %s", err) + } + + return nil +} + +func resourceAwsNetworkManagerDeviceUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + + if d.HasChange("tags") { + o, n := d.GetChange("tags") + + if err := keyvaluetags.NetworkmanagerUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { + return fmt.Errorf("error updating Network Manager Device (%s) tags: %s", d.Id(), err) + } + } + + return nil +} + +func resourceAwsNetworkManagerDeviceDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + + input := &networkmanager.DeleteDeviceInput{ + GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), + DeviceId: aws.String(d.Id()), + } + + log.Printf("[DEBUG] Deleting Network Manager Device (%s): %s", d.Id(), input) + err := resource.Retry(2*time.Minute, func() *resource.RetryError { + _, err := conn.DeleteDevice(input) + + if isAWSErr(err, "IncorrectState", "has non-deleted Device Associations") { + return resource.RetryableError(err) + } + + if isAWSErr(err, "IncorrectState", "has non-deleted Device") { + return resource.RetryableError(err) + } + + if err != nil { + return resource.NonRetryableError(err) + } + + return nil + }) + + if isResourceTimeoutError(err) { + _, err = conn.DeleteDevice(input) + } + + if isAWSErr(err, "InvalidDeviceID.NotFound", "") { + return nil + } + + if err != nil { + return fmt.Errorf("error deleting Network Manager Device: %s", err) + } + + if err := waitForNetworkManagerDeviceDeletion(conn, d.Get("global_network_id").(string), d.Id()); err != nil { + return fmt.Errorf("error waiting for Network Manager Device (%s) deletion: %s", d.Id(), err) + } + + return nil +} + +func resourceAwsNetworkManagerDeviceLocation(d *schema.ResourceData) *networkmanager.Location { + count := d.Get("location.#").(int) + if count == 0 { + return nil + } + + return &networkmanager.Location{ + Address: aws.String(d.Get("location.0.address").(string)), + Latitude: aws.String(d.Get("location.0.latitude").(string)), + Longitude: aws.String(d.Get("location.0.longitude").(string)), + } +} +func networkmanagerDeviceRefreshFunc(conn *networkmanager.NetworkManager, globalNetworkID, deviceID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + device, err := networkmanagerDescribeDevice(conn, globalNetworkID, deviceID) + + if isAWSErr(err, "InvalidDeviceID.NotFound", "") { + return nil, "DELETED", nil + } + + if err != nil { + return nil, "", fmt.Errorf("error reading Network Manager Device (%s): %s", deviceID, err) + } + + if device == nil { + return nil, "DELETED", nil + } + + return device, aws.StringValue(device.State), nil + } +} + +func networkmanagerDescribeDevice(conn *networkmanager.NetworkManager, globalNetworkID, deviceID string) (*networkmanager.Device, error) { + input := &networkmanager.GetDevicesInput{ + GlobalNetworkId: aws.String(globalNetworkID), + DeviceIds: []*string{aws.String(deviceID)}, + } + + log.Printf("[DEBUG] Reading Network Manager Device (%s): %s", deviceID, input) + for { + output, err := conn.GetDevices(input) + + if err != nil { + return nil, err + } + + if output == nil || len(output.Devices) == 0 { + return nil, nil + } + + for _, device := range output.Devices { + if device == nil { + continue + } + + if aws.StringValue(device.DeviceId) == deviceID { + return device, nil + } + } + + if aws.StringValue(output.NextToken) == "" { + break + } + + input.NextToken = output.NextToken + } + + return nil, nil +} + +func waitForNetworkManagerDeviceDeletion(conn *networkmanager.NetworkManager, globalNetworkID, deviceID string) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{ + networkmanager.DeviceStateAvailable, + networkmanager.DeviceStateDeleting, + }, + Target: []string{""}, + Refresh: networkmanagerDeviceRefreshFunc(conn, globalNetworkID, deviceID), + Timeout: 10 * time.Minute, + NotFoundChecks: 1, + } + + log.Printf("[DEBUG] Waiting for Network Manager Device (%s) deletion", deviceID) + _, err := stateConf.WaitForState() + + if isResourceNotFoundError(err) { + return nil + } + + return err +} From 465ec46bd80e8eca214a3fa9346ffec6a1c202e8 Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Wed, 13 May 2020 22:14:15 +0100 Subject: [PATCH 008/229] r/aws_networkmanager_device: tests output from acceptance tests: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSNetworkManagerDevice' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSNetworkManagerDevice -timeout 120m MYDEBUG: resourceAwsNetworkManagerLink() === RUN TestAccAWSNetworkManagerDevice_basic === PAUSE TestAccAWSNetworkManagerDevice_basic === RUN TestAccAWSNetworkManagerDevice_tags === PAUSE TestAccAWSNetworkManagerDevice_tags === CONT TestAccAWSNetworkManagerDevice_basic === CONT TestAccAWSNetworkManagerDevice_tags --- PASS: TestAccAWSNetworkManagerDevice_basic (79.77s) --- PASS: TestAccAWSNetworkManagerDevice_tags (127.77s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 128.780s --- ...resource_aws_networkmanager_device_test.go | 340 ++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100644 aws/resource_aws_networkmanager_device_test.go diff --git a/aws/resource_aws_networkmanager_device_test.go b/aws/resource_aws_networkmanager_device_test.go new file mode 100644 index 00000000000..1ca1912e41c --- /dev/null +++ b/aws/resource_aws_networkmanager_device_test.go @@ -0,0 +1,340 @@ +package aws + +import ( + "fmt" + "log" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func init() { + resource.AddTestSweepers("aws_networkmanager_device", &resource.Sweeper{ + Name: "aws_networkmanager_device", + F: testSweepNetworkManagerDevice, + }) +} + +func testSweepNetworkManagerDevice(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*AWSClient).networkmanagerconn + var sweeperErrs *multierror.Error + + err = conn.GetDevicesPages(&networkmanager.GetDevicesInput{}, + func(page *networkmanager.GetDevicesOutput, lastPage bool) bool { + for _, device := range page.Devices { + input := &networkmanager.DeleteDeviceInput{ + GlobalNetworkId: device.GlobalNetworkId, + DeviceId: device.DeviceId, + } + id := aws.StringValue(device.DeviceId) + globalNetworkID := aws.StringValue(device.GlobalNetworkId) + + log.Printf("[INFO] Deleting Network Manager Device: %s", id) + _, err := conn.DeleteDevice(input) + + if isAWSErr(err, "InvalidDeviceID.NotFound", "") { + continue + } + + if err != nil { + sweeperErr := fmt.Errorf("failed to delete Network Manager Device %s: %s", id, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + + if err := waitForNetworkManagerDeviceDeletion(conn, globalNetworkID, id); err != nil { + sweeperErr := fmt.Errorf("error waiting for Network Manager Device (%s) deletion: %s", id, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + return !lastPage + }) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping Network Manager Device sweep for %s: %s", region, err) + return nil + } + + if err != nil { + return fmt.Errorf("Error retrieving Network Manager Devices: %s", err) + } + + return sweeperErrs.ErrorOrNil() +} + +func TestAccAWSNetworkManagerDevice_basic(t *testing.T) { + resourceName := "aws_networkmanager_device.test" + siteResourceName := "aws_networkmanager_site.test" + site2ResourceName := "aws_networkmanager_site.test2" + gloablNetworkResourceName := "aws_networkmanager_global_network.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsNetworkManagerDeviceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccNetworkManagerDeviceConfig("test"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerDeviceExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetworkResourceName, "id"), + resource.TestCheckResourceAttrPair(resourceName, "site_id", siteResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "description", "test"), + resource.TestCheckResourceAttr(resourceName, "model", "abc"), + resource.TestCheckResourceAttr(resourceName, "serial_number", "123"), + resource.TestCheckResourceAttr(resourceName, "type", "office device"), + resource.TestCheckResourceAttr(resourceName, "vendor", "company"), + resource.TestCheckResourceAttr(resourceName, "location.#", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccAWSNetworkManagerDeviceImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, + { + Config: testAccNetworkManagerDeviceConfig_Update("test updated", "def", "456", "home device", "othercompany", "18.0029784", "-76.7897987"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerDeviceExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetworkResourceName, "id"), + resource.TestCheckResourceAttrPair(resourceName, "site_id", site2ResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "description", "test updated"), + resource.TestCheckResourceAttr(resourceName, "model", "def"), + resource.TestCheckResourceAttr(resourceName, "serial_number", "456"), + resource.TestCheckResourceAttr(resourceName, "type", "home device"), + resource.TestCheckResourceAttr(resourceName, "vendor", "othercompany"), + resource.TestCheckResourceAttr(resourceName, "location.#", "1"), + resource.TestCheckResourceAttr(resourceName, "location.0.address", ""), + resource.TestCheckResourceAttr(resourceName, "location.0.latitude", "18.0029784"), + resource.TestCheckResourceAttr(resourceName, "location.0.longitude", "-76.7897987"), + ), + }, + }, + }) +} + +func TestAccAWSNetworkManagerDevice_tags(t *testing.T) { + resourceName := "aws_networkmanager_device.test" + description := "test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsNetworkManagerDeviceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccNetworkManagerDeviceConfigTags1(description, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerDeviceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "test"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccAWSNetworkManagerDeviceImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, + { + Config: testAccNetworkManagerDeviceConfigTags2(description, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerDeviceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "test"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccNetworkManagerDeviceConfigTags1(description, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerDeviceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "test"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + }, + }) +} + +func testAccCheckAwsNetworkManagerDeviceDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_networkmanager_device" { + continue + } + + device, err := networkmanagerDescribeDevice(conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) + if err != nil { + if isAWSErr(err, networkmanager.ErrCodeValidationException, "") { + return nil + } + return err + } + + if device == nil { + continue + } + + return fmt.Errorf("Expected Device to be destroyed, %s found", rs.Primary.ID) + } + + return nil +} + +func testAccCheckAwsNetworkManagerDeviceExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn + + device, err := networkmanagerDescribeDevice(conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) + + if err != nil { + return err + } + + if device == nil { + return fmt.Errorf("Network Manager Device not found") + } + + if aws.StringValue(device.State) != networkmanager.DeviceStateAvailable && aws.StringValue(device.State) != networkmanager.DeviceStatePending { + return fmt.Errorf("Network Manager Device (%s) exists in (%s) state", rs.Primary.ID, aws.StringValue(device.State)) + } + + return err + } +} + +func testAccNetworkManagerDeviceConfig(description string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = "test" +} + +resource "aws_networkmanager_site" "test" { + description = "test" + global_network_id = "${aws_networkmanager_global_network.test.id}" +} + +resource "aws_networkmanager_device" "test" { + description = %q + global_network_id = "${aws_networkmanager_global_network.test.id}" + site_id = "${aws_networkmanager_site.test.id}" + model = "abc" + serial_number = "123" + type = "office device" + vendor = "company" +} +`, description) +} + +func testAccNetworkManagerDeviceConfigTags1(description, tagKey1, tagValue1 string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = "test" +} + +resource "aws_networkmanager_site" "test" { + description = "test" + global_network_id = "${aws_networkmanager_global_network.test.id}" +} + +resource "aws_networkmanager_device" "test" { + description = %q + global_network_id = "${aws_networkmanager_global_network.test.id}" + site_id = "${aws_networkmanager_site.test.id}" + + tags = { + %q = %q + } +} +`, description, tagKey1, tagValue1) +} + +func testAccNetworkManagerDeviceConfigTags2(description, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = "test" +} + +resource "aws_networkmanager_site" "test" { + description = "test" + global_network_id = "${aws_networkmanager_global_network.test.id}" +} + +resource "aws_networkmanager_device" "test" { + description = %q + global_network_id = "${aws_networkmanager_global_network.test.id}" + + tags = { + %q = %q + %q = %q + } +} +`, description, tagKey1, tagValue1, tagKey2, tagValue2) +} + +func testAccNetworkManagerDeviceConfig_Update(description, model, serial_number, device_type, vendor, latitude, longitude string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = "test" +} + +resource "aws_networkmanager_site" "test" { + description = "test" + global_network_id = "${aws_networkmanager_global_network.test.id}" +} + +resource "aws_networkmanager_site" "test2" { + description = "test2" + global_network_id = "${aws_networkmanager_global_network.test.id}" +} + +resource "aws_networkmanager_device" "test" { + description = %q + global_network_id = "${aws_networkmanager_global_network.test.id}" + site_id = "${aws_networkmanager_site.test2.id}" + model = %q + serial_number = %q + type = %q + vendor = %q + + location { + latitude = %q + longitude = %q + } +} +`, description, model, serial_number, device_type, vendor, latitude, longitude) +} + +func testAccAWSNetworkManagerDeviceImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("Not found: %s", resourceName) + } + + return rs.Primary.Attributes["arn"], nil + } +} From dac343d45142a9106a0efb869d82a163db639dee Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Thu, 14 May 2020 17:48:40 +0100 Subject: [PATCH 009/229] r/aws_networkmanager_transit_gateway_registration: initial configuration --- aws/provider.go | 1 + ...orkmanager_transit_gateway_registration.go | 239 ++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 aws/resource_aws_networkmanager_transit_gateway_registration.go diff --git a/aws/provider.go b/aws/provider.go index dd472d0ab03..0bb3aa26b18 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -699,6 +699,7 @@ func Provider() terraform.ResourceProvider { "aws_networkmanager_device": resourceAwsNetworkManagerDevice(), "aws_networkmanager_global_network": resourceAwsNetworkManagerGlobalNetwork(), "aws_networkmanager_site": resourceAwsNetworkManagerSite(), + "aws_networkmanager_transit_gateway_registration": resourceAwsNetworkManagerTransitGatewayRegistration(), "aws_opsworks_application": resourceAwsOpsworksApplication(), "aws_opsworks_stack": resourceAwsOpsworksStack(), "aws_opsworks_java_app_layer": resourceAwsOpsworksJavaAppLayer(), diff --git a/aws/resource_aws_networkmanager_transit_gateway_registration.go b/aws/resource_aws_networkmanager_transit_gateway_registration.go new file mode 100644 index 00000000000..1fcca2edbd3 --- /dev/null +++ b/aws/resource_aws_networkmanager_transit_gateway_registration.go @@ -0,0 +1,239 @@ +package aws + +import ( + "fmt" + "log" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/arn" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func resourceAwsNetworkManagerTransitGatewayRegistration() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsNetworkManagerTransitGatewayRegistrationCreate, + Read: resourceAwsNetworkManagerTransitGatewayRegistrationRead, + Delete: resourceAwsNetworkManagerTransitGatewayRegistrationDelete, + Importer: &schema.ResourceImporter{ + State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + idErr := fmt.Errorf("Expected ID in format of arn:aws:ec2:REGION:ACCOUNTID:transit-gateway/TGWID,GLOBALNETWORKID and provided: %s", d.Id()) + + identifiers := strings.Split(d.Id(), ",") + if len(identifiers) != 2 { + return nil, idErr + } + if arn.IsARN(identifiers[0]) { + d.Set("transit_gateway_arn", identifiers[0]) + } else { + return nil, idErr + } + + d.Set("global_network_id", identifiers[1]) + + return []*schema.ResourceData{d}, nil + }, + }, + + Schema: map[string]*schema.Schema{ + "global_network_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "transit_gateway_arn": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + } +} + +func resourceAwsNetworkManagerTransitGatewayRegistrationCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + + globalNetworkId := d.Get("global_network_id").(string) + transitGatewayArn := d.Get("transit_gateway_arn").(string) + + input := &networkmanager.RegisterTransitGatewayInput{ + GlobalNetworkId: aws.String(globalNetworkId), + TransitGatewayArn: aws.String(transitGatewayArn), + } + + log.Printf("[DEBUG] Creating Network Manager Transit gateway Registration: %s", input) + + output, err := conn.RegisterTransitGateway(input) + if err != nil { + return fmt.Errorf("error creating Network Manager Transit Gateway Registration: %s", err) + } + + d.SetId(fmt.Sprintf("%s,%s", transitGatewayArn, globalNetworkId)) + + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.TransitGatewayRegistrationStatePending}, + Target: []string{networkmanager.TransitGatewayRegistrationStateAvailable}, + Refresh: networkmanagerTransitGatewayRegistrationRefreshFunc(conn, aws.StringValue(output.TransitGatewayRegistration.GlobalNetworkId), aws.StringValue(output.TransitGatewayRegistration.TransitGatewayArn)), + Timeout: 10 * time.Minute, + } + + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf("error waiting for Network Manager Transit Gateway Registration (%s) availability: %s", d.Id(), err) + } + + return resourceAwsNetworkManagerTransitGatewayRegistrationRead(d, meta) +} + +func resourceAwsNetworkManagerTransitGatewayRegistrationRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + + transitGatewayRegistration, err := networkmanagerDescribeTransitGatewayRegistration(conn, d.Get("global_network_id").(string), d.Get("transit_gateway_arn").(string)) + + if isAWSErr(err, "InvalidTransitGatewayRegistrationID.NotFound", "") { + log.Printf("[WARN] Network Manager Transit Gateway Registration (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return fmt.Errorf("error reading Network Manager Transit Gateway Registration: %s", err) + } + + if transitGatewayRegistration == nil { + log.Printf("[WARN] Network Manager Transit Gateway Registration (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if aws.StringValue(transitGatewayRegistration.State.Code) == networkmanager.TransitGatewayRegistrationStateDeleting || aws.StringValue(transitGatewayRegistration.State.Code) == networkmanager.TransitGatewayRegistrationStateDeleted { + log.Printf("[WARN] Network Manager Transit Gateway Registration (%s) in deleted state (%s,%s), removing from state", d.Id(), aws.StringValue(transitGatewayRegistration.State.Code), aws.StringValue(transitGatewayRegistration.State.Message)) + d.SetId("") + return nil + } + + return nil +} + +func resourceAwsNetworkManagerTransitGatewayRegistrationDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + + input := &networkmanager.DeregisterTransitGatewayInput{ + GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), + TransitGatewayArn: aws.String(d.Get("transit_gateway_arn").(string)), + } + + log.Printf("[DEBUG] Deleting Network Manager Transit Gateway Registration (%s): %s", d.Id(), input) + err := resource.Retry(2*time.Minute, func() *resource.RetryError { + req, _ := conn.DeregisterTransitGatewayRequest(input) + if err := req.Send(); err != nil { + return resource.NonRetryableError(err) + } + + return nil + }) + + if isResourceTimeoutError(err) { + req, _ := conn.DeregisterTransitGatewayRequest(input) + err = req.Send() + } + + if isAWSErr(err, "InvalidTransitGatewayRegistrationArn.NotFound", "") { + return nil + } + + if err != nil { + return fmt.Errorf("error deleting Network Manager Transit Gateway Registration: %s", err) + } + + if err := waitForNetworkManagerTransitGatewayRegistrationDeletion(conn, d.Get("global_network_id").(string), d.Get("transit_gateway_arn").(string)); err != nil { + return fmt.Errorf("error waiting for Network Manager Transit Gateway Registration (%s) deletion: %s", d.Id(), err) + } + + return nil +} + +func networkmanagerTransitGatewayRegistrationRefreshFunc(conn *networkmanager.NetworkManager, globalNetworkID, transitGatewayArn string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + transitGatewayRegistration, err := networkmanagerDescribeTransitGatewayRegistration(conn, globalNetworkID, transitGatewayArn) + + if isAWSErr(err, "InvalidTransitGatewayRegistrationID.NotFound", "") { + return nil, "DELETED", nil + } + + if err != nil { + return nil, "", fmt.Errorf("error reading Network Manager Transit Gateway Registration (%s,%s): %s", transitGatewayArn, globalNetworkID, err) + } + + if transitGatewayRegistration == nil { + return nil, "DELETED", nil + } + + return transitGatewayRegistration, aws.StringValue(transitGatewayRegistration.State.Code), nil + } +} + +func networkmanagerDescribeTransitGatewayRegistration(conn *networkmanager.NetworkManager, globalNetworkID, transitGatewayArn string) (*networkmanager.TransitGatewayRegistration, error) { + input := &networkmanager.GetTransitGatewayRegistrationsInput{ + GlobalNetworkId: aws.String(globalNetworkID), + TransitGatewayArns: []*string{aws.String(transitGatewayArn)}, + } + + log.Printf("[DEBUG] Reading Network Manager Transit Gateway Registration (%s): %s", transitGatewayArn, input) + for { + output, err := conn.GetTransitGatewayRegistrations(input) + + if err != nil { + return nil, err + } + + if output == nil || len(output.TransitGatewayRegistrations) == 0 { + return nil, nil + } + + for _, transitGatewayRegistration := range output.TransitGatewayRegistrations { + if transitGatewayRegistration == nil { + continue + } + + if aws.StringValue(transitGatewayRegistration.TransitGatewayArn) == transitGatewayArn { + return transitGatewayRegistration, nil + } + } + + if aws.StringValue(output.NextToken) == "" { + break + } + + input.NextToken = output.NextToken + } + + return nil, nil +} + +func waitForNetworkManagerTransitGatewayRegistrationDeletion(conn *networkmanager.NetworkManager, globalNetworkID, transitGatewayArn string) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{ + networkmanager.TransitGatewayRegistrationStateAvailable, + networkmanager.TransitGatewayRegistrationStateDeleting, + }, + Target: []string{ + networkmanager.TransitGatewayRegistrationStateDeleted, + }, + Refresh: networkmanagerTransitGatewayRegistrationRefreshFunc(conn, globalNetworkID, transitGatewayArn), + Timeout: 10 * time.Minute, + NotFoundChecks: 1, + } + + log.Printf("[DEBUG] Waiting for Network Manager Transit Gateway Registration (%s) deletion", transitGatewayArn) + _, err := stateConf.WaitForState() + + if isResourceNotFoundError(err) { + return nil + } + + return err +} From 6975c302973c0a426265e0900080aa168a4ef243 Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Thu, 14 May 2020 17:49:02 +0100 Subject: [PATCH 010/229] r/aws_networkmanager_transit_gateway_registration: tests Output from acceptance test: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSNetworkManagerTransitGatewayRegistration' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSNetworkManagerTransitGatewayRegistration -timeout 120m === RUN TestAccAWSNetworkManagerTransitGatewayRegistration_basic === PAUSE TestAccAWSNetworkManagerTransitGatewayRegistration_basic === CONT TestAccAWSNetworkManagerTransitGatewayRegistration_basic --- PASS: TestAccAWSNetworkManagerTransitGatewayRegistration_basic (237.71s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 238.925s --- ...nager_transit_gateway_registration_test.go | 176 ++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 aws/resource_aws_networkmanager_transit_gateway_registration_test.go diff --git a/aws/resource_aws_networkmanager_transit_gateway_registration_test.go b/aws/resource_aws_networkmanager_transit_gateway_registration_test.go new file mode 100644 index 00000000000..f83f36b03e2 --- /dev/null +++ b/aws/resource_aws_networkmanager_transit_gateway_registration_test.go @@ -0,0 +1,176 @@ +package aws + +import ( + "fmt" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "log" + "testing" +) + +func init() { + resource.AddTestSweepers("aws_networkmanager_transit_gateway_registration", &resource.Sweeper{ + Name: "aws_networkmanager_transit_gateway_registration", + F: testSweepNetworkManagerTransitGatewayRegistration, + }) +} +func testSweepNetworkManagerTransitGatewayRegistration(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*AWSClient).networkmanagerconn + var sweeperErrs *multierror.Error + err = conn.GetTransitGatewayRegistrationsPages(&networkmanager.GetTransitGatewayRegistrationsInput{}, + func(page *networkmanager.GetTransitGatewayRegistrationsOutput, lastPage bool) bool { + for _, transitGatewayRegistration := range page.TransitGatewayRegistrations { + input := &networkmanager.DeregisterTransitGatewayInput{ + GlobalNetworkId: transitGatewayRegistration.GlobalNetworkId, + TransitGatewayArn: transitGatewayRegistration.TransitGatewayArn, + } + transitGatewayArn := aws.StringValue(transitGatewayRegistration.TransitGatewayArn) + globalNetworkID := aws.StringValue(transitGatewayRegistration.GlobalNetworkId) + log.Printf("[INFO] Deleting Network Manager Transit Gateway Registration: %s", transitGatewayArn) + req, _ := conn.DeregisterTransitGatewayRequest(input) + err = req.Send() + if isAWSErr(err, "InvalidTransitGatewayRegistrationArn.NotFound", "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("failed to delete Network Manager Transit Gateway Registration %s: %s", transitGatewayArn, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + if err := waitForNetworkManagerTransitGatewayRegistrationDeletion(conn, globalNetworkID, transitGatewayArn); err != nil { + sweeperErr := fmt.Errorf("error waiting for Network Manager Transit Gateway Registration (%s) deletion: %s", transitGatewayArn, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + return !lastPage + }) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping Network Manager Transit Gateway Registration sweep for %s: %s", region, err) + return nil + } + if err != nil { + return fmt.Errorf("Error retrieving Network Manager Transit Gateway Registrations: %s", err) + } + return sweeperErrs.ErrorOrNil() +} +func TestAccAWSNetworkManagerTransitGatewayRegistration_basic(t *testing.T) { + resourceName := "aws_networkmanager_transit_gateway_registration.test" + gloablNetworkResourceName := "aws_networkmanager_global_network.test" + gloablNetwork2ResourceName := "aws_networkmanager_global_network.test2" + transitGatewayResourceName := "aws_ec2_transit_gateway.test" + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSEc2TransitGateway(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsNetworkManagerTransitGatewayRegistrationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccNetworkManagerTransitGatewayRegistrationConfig(), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerTransitGatewayRegistrationExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetworkResourceName, "id"), + resource.TestCheckResourceAttrPair(resourceName, "transit_gateway_arn", transitGatewayResourceName, "arn"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccAWSNetworkManagerTransitGatewayRegistrationImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, + { + Config: testAccNetworkManagerTransitGatewayRegistrationConfig_Update(), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsNetworkManagerTransitGatewayRegistrationExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetwork2ResourceName, "id"), + resource.TestCheckResourceAttrPair(resourceName, "transit_gateway_arn", transitGatewayResourceName, "arn"), + ), + }, + }, + }) +} +func testAccCheckAwsNetworkManagerTransitGatewayRegistrationDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_networkmanager_transit_gateway_registration" { + continue + } + transitGatewayArn, err := networkmanagerDescribeTransitGatewayRegistration(conn, rs.Primary.Attributes["global_network_id"], rs.Primary.Attributes["transit_gateway_arn"]) + if err != nil { + if isAWSErr(err, networkmanager.ErrCodeValidationException, "") { + return nil + } + return err + } + if transitGatewayArn == nil { + continue + } + return fmt.Errorf("Expected Transit Gateway Registration to be destroyed, %s found", rs.Primary.ID) + } + return nil +} +func testAccCheckAwsNetworkManagerTransitGatewayRegistrationExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn + transitGatewayArn, err := networkmanagerDescribeTransitGatewayRegistration(conn, rs.Primary.Attributes["global_network_id"], rs.Primary.Attributes["transit_gateway_arn"]) + if err != nil { + return err + } + if transitGatewayArn == nil { + return fmt.Errorf("Network Manager Transit Gateway Registration not found") + } + if aws.StringValue(transitGatewayArn.State.Code) != networkmanager.TransitGatewayRegistrationStateAvailable && aws.StringValue(transitGatewayArn.State.Code) != networkmanager.TransitGatewayRegistrationStatePending { + return fmt.Errorf("Network Manager Transit Gateway Registration (%s) exists in (%s) state", rs.Primary.Attributes["transit_gateway_arn"], aws.StringValue(transitGatewayArn.State.Code)) + } + return err + } +} +func testAccNetworkManagerTransitGatewayRegistrationConfig() string { + return ` +resource "aws_networkmanager_global_network" "test" { + description = "test" +} +resource "aws_ec2_transit_gateway" "test" {} +resource "aws_networkmanager_transit_gateway_registration" "test" { + global_network_id = "${aws_networkmanager_global_network.test.id}" + transit_gateway_arn = "${aws_ec2_transit_gateway.test.arn}" +} +` +} +func testAccNetworkManagerTransitGatewayRegistrationConfig_Update() string { + return ` +resource "aws_networkmanager_global_network" "test" { + description = "test" +} +resource "aws_networkmanager_global_network" "test2" { + description = "test2" +} +resource "aws_ec2_transit_gateway" "test" {} +resource "aws_networkmanager_transit_gateway_registration" "test" { + global_network_id = "${aws_networkmanager_global_network.test2.id}" + transit_gateway_arn = "${aws_ec2_transit_gateway.test.arn}" +} +` +} +func testAccAWSNetworkManagerTransitGatewayRegistrationImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("Not found: %s", resourceName) + } + return fmt.Sprintf("%s,%s", rs.Primary.Attributes["transit_gateway_arn"], rs.Primary.Attributes["global_network_id"]), nil + } +} From 70273f2d7d49ebbfda31d22c686389cb482dca76 Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Fri, 15 May 2020 00:14:24 +0100 Subject: [PATCH 011/229] r/aws_networkmanager_*: fix code lint errors R004: ResourceData.Set() incompatible value type: *github.com/aws/aws-sdk-go/service/networkmanager.Location resource_aws_networkmanager_device.go resource_aws_networkmanager_site.go R006: RetryFunc should include RetryableError() handling or be removed resource_aws_networkmanager_transit_gateway_registration --- aws/resource_aws_networkmanager_device.go | 19 ++++---------- aws/resource_aws_networkmanager_site.go | 20 ++++---------- ...orkmanager_transit_gateway_registration.go | 15 ++--------- aws/structure.go | 26 +++++++++++++++++++ 4 files changed, 38 insertions(+), 42 deletions(-) diff --git a/aws/resource_aws_networkmanager_device.go b/aws/resource_aws_networkmanager_device.go index aea232261e1..84805c7c22c 100644 --- a/aws/resource_aws_networkmanager_device.go +++ b/aws/resource_aws_networkmanager_device.go @@ -111,7 +111,7 @@ func resourceAwsNetworkManagerDeviceCreate(d *schema.ResourceData, meta interfac input := &networkmanager.CreateDeviceInput{ Description: aws.String(d.Get("description").(string)), GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), - Location: resourceAwsNetworkManagerDeviceLocation(d), + Location: expandNetworkManagerLocation(d.Get("location").([]interface{})), Model: aws.String(d.Get("model").(string)), SerialNumber: aws.String(d.Get("serial_number").(string)), SiteId: aws.String(d.Get("site_id").(string)), @@ -174,13 +174,16 @@ func resourceAwsNetworkManagerDeviceRead(d *schema.ResourceData, meta interface{ d.Set("arn", device.DeviceArn) d.Set("description", device.Description) - d.Set("location", device.Location) d.Set("model", device.Model) d.Set("serial_number", device.SerialNumber) d.Set("site_id", device.SiteId) d.Set("type", device.Type) d.Set("vendor", device.Vendor) + if err := d.Set("location", flattenNetworkManagerLocation(device.Location)); err != nil { + return fmt.Errorf("error setting location: %s", err) + } + if err := d.Set("tags", keyvaluetags.NetworkmanagerKeyValueTags(device.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { return fmt.Errorf("error setting tags: %s", err) } @@ -248,18 +251,6 @@ func resourceAwsNetworkManagerDeviceDelete(d *schema.ResourceData, meta interfac return nil } -func resourceAwsNetworkManagerDeviceLocation(d *schema.ResourceData) *networkmanager.Location { - count := d.Get("location.#").(int) - if count == 0 { - return nil - } - - return &networkmanager.Location{ - Address: aws.String(d.Get("location.0.address").(string)), - Latitude: aws.String(d.Get("location.0.latitude").(string)), - Longitude: aws.String(d.Get("location.0.longitude").(string)), - } -} func networkmanagerDeviceRefreshFunc(conn *networkmanager.NetworkManager, globalNetworkID, deviceID string) resource.StateRefreshFunc { return func() (interface{}, string, error) { device, err := networkmanagerDescribeDevice(conn, globalNetworkID, deviceID) diff --git a/aws/resource_aws_networkmanager_site.go b/aws/resource_aws_networkmanager_site.go index af75fe5981c..2d8b57cc956 100644 --- a/aws/resource_aws_networkmanager_site.go +++ b/aws/resource_aws_networkmanager_site.go @@ -90,7 +90,7 @@ func resourceAwsNetworkManagerSiteCreate(d *schema.ResourceData, meta interface{ input := &networkmanager.CreateSiteInput{ Description: aws.String(d.Get("description").(string)), GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), - Location: resourceAwsNetworkManagerSiteLocation(d), + Location: expandNetworkManagerLocation(d.Get("location").([]interface{})), Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().NetworkmanagerTags(), } @@ -148,7 +148,10 @@ func resourceAwsNetworkManagerSiteRead(d *schema.ResourceData, meta interface{}) d.Set("arn", site.SiteArn) d.Set("description", site.Description) - d.Set("location", site.Location) + + if err := d.Set("location", flattenNetworkManagerLocation(site.Location)); err != nil { + return fmt.Errorf("error setting location: %s", err) + } if err := d.Set("tags", keyvaluetags.NetworkmanagerKeyValueTags(site.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { return fmt.Errorf("error setting tags: %s", err) @@ -217,19 +220,6 @@ func resourceAwsNetworkManagerSiteDelete(d *schema.ResourceData, meta interface{ return nil } -func resourceAwsNetworkManagerSiteLocation(d *schema.ResourceData) *networkmanager.Location { - count := d.Get("location.#").(int) - if count == 0 { - return nil - } - - return &networkmanager.Location{ - Address: aws.String(d.Get("location.0.address").(string)), - Latitude: aws.String(d.Get("location.0.latitude").(string)), - Longitude: aws.String(d.Get("location.0.longitude").(string)), - } -} - func networkmanagerSiteRefreshFunc(conn *networkmanager.NetworkManager, globalNetworkID, siteID string) resource.StateRefreshFunc { return func() (interface{}, string, error) { site, err := networkmanagerDescribeSite(conn, globalNetworkID, siteID) diff --git a/aws/resource_aws_networkmanager_transit_gateway_registration.go b/aws/resource_aws_networkmanager_transit_gateway_registration.go index 1fcca2edbd3..0be56924a58 100644 --- a/aws/resource_aws_networkmanager_transit_gateway_registration.go +++ b/aws/resource_aws_networkmanager_transit_gateway_registration.go @@ -127,19 +127,8 @@ func resourceAwsNetworkManagerTransitGatewayRegistrationDelete(d *schema.Resourc } log.Printf("[DEBUG] Deleting Network Manager Transit Gateway Registration (%s): %s", d.Id(), input) - err := resource.Retry(2*time.Minute, func() *resource.RetryError { - req, _ := conn.DeregisterTransitGatewayRequest(input) - if err := req.Send(); err != nil { - return resource.NonRetryableError(err) - } - - return nil - }) - - if isResourceTimeoutError(err) { - req, _ := conn.DeregisterTransitGatewayRequest(input) - err = req.Send() - } + req, _ := conn.DeregisterTransitGatewayRequest(input) + err := req.Send() if isAWSErr(err, "InvalidTransitGatewayRegistrationArn.NotFound", "") { return nil diff --git a/aws/structure.go b/aws/structure.go index 6ebb5317484..0f2a3ca8028 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -38,6 +38,7 @@ import ( "github.com/aws/aws-sdk-go/service/macie" "github.com/aws/aws-sdk-go/service/mq" "github.com/aws/aws-sdk-go/service/neptune" + "github.com/aws/aws-sdk-go/service/networkmanager" "github.com/aws/aws-sdk-go/service/rds" "github.com/aws/aws-sdk-go/service/redshift" "github.com/aws/aws-sdk-go/service/route53" @@ -3655,6 +3656,31 @@ func flattenCognitoIdentityPoolRolesAttachmentMappingRules(d []*cognitoidentity. return rules } +func flattenNetworkManagerLocation(location *networkmanager.Location) []interface{} { + if location == nil { + return []interface{}{} + } + m := map[string]interface{}{ + "address": aws.StringValue(location.Address), + "latitude": aws.StringValue(location.Latitude), + "longitude": aws.StringValue(location.Longitude), + } + return []interface{}{m} +} + +func expandNetworkManagerLocation(l []interface{}) *networkmanager.Location { + if len(l) == 0 || l[0] == nil { + return nil + } + m := l[0].(map[string]interface{}) + logs := &networkmanager.Location{ + Address: aws.String(m["address"].(string)), + Latitude: aws.String(m["latitude"].(string)), + Longitude: aws.String(m["longitude"].(string)), + } + return logs +} + func flattenRedshiftLogging(ls *redshift.LoggingStatus) []interface{} { if ls == nil { return []interface{}{} From 125cf56720e1a7749eb90af79924f976d69c2292 Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Fri, 15 May 2020 21:45:34 +0100 Subject: [PATCH 012/229] r/aws_networkmanager_*: support updating optional arguments --- aws/resource_aws_networkmanager_device.go | 21 +++++++++++++++++-- ...ource_aws_networkmanager_global_network.go | 13 +++++++++++- aws/resource_aws_networkmanager_site.go | 15 ++++++++++++- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/aws/resource_aws_networkmanager_device.go b/aws/resource_aws_networkmanager_device.go index 84805c7c22c..afaa263516c 100644 --- a/aws/resource_aws_networkmanager_device.go +++ b/aws/resource_aws_networkmanager_device.go @@ -51,7 +51,6 @@ func resourceAwsNetworkManagerDevice() *schema.Resource { "description": { Type: schema.TypeString, Optional: true, - ForceNew: true, }, "global_network_id": { Type: schema.TypeString, @@ -90,7 +89,6 @@ func resourceAwsNetworkManagerDevice() *schema.Resource { "site_id": { Type: schema.TypeString, Optional: true, - ForceNew: true, }, "tags": tagsSchema(), "type": { @@ -194,6 +192,25 @@ func resourceAwsNetworkManagerDeviceRead(d *schema.ResourceData, meta interface{ func resourceAwsNetworkManagerDeviceUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn + if d.HasChange("description") || d.HasChange("location") || d.HasChange("model") || d.HasChange("serial_number") || d.HasChange("site_id") || d.HasChange("type") || d.HasChange("vendor") { + request := &networkmanager.UpdateDeviceInput{ + Description: aws.String(d.Get("description").(string)), + DeviceId: aws.String(d.Id()), + GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), + Location: expandNetworkManagerLocation(d.Get("location").([]interface{})), + Model: aws.String(d.Get("model").(string)), + SerialNumber: aws.String(d.Get("serial_number").(string)), + SiteId: aws.String(d.Get("site_id").(string)), + Type: aws.String(d.Get("type").(string)), + Vendor: aws.String(d.Get("vendor").(string)), + } + + _, err := conn.UpdateDevice(request) + if err != nil { + return fmt.Errorf("Failure updating Network Manager Device (%s): %s", d.Id(), err) + } + } + if d.HasChange("tags") { o, n := d.GetChange("tags") diff --git a/aws/resource_aws_networkmanager_global_network.go b/aws/resource_aws_networkmanager_global_network.go index 380ae8e36fc..a8efae3cb7e 100644 --- a/aws/resource_aws_networkmanager_global_network.go +++ b/aws/resource_aws_networkmanager_global_network.go @@ -30,7 +30,6 @@ func resourceAwsNetworkManagerGlobalNetwork() *schema.Resource { "description": { Type: schema.TypeString, Optional: true, - ForceNew: true, }, "tags": tagsSchema(), }, @@ -113,6 +112,18 @@ func resourceAwsNetworkManagerGlobalNetworkRead(d *schema.ResourceData, meta int func resourceAwsNetworkManagerGlobalNetworkUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn + if d.HasChange("description") { + request := &networkmanager.UpdateGlobalNetworkInput{ + Description: aws.String(d.Get("description").(string)), + GlobalNetworkId: aws.String(d.Id()), + } + + _, err := conn.UpdateGlobalNetwork(request) + if err != nil { + return fmt.Errorf("Failure updating Network Manager Global Network description: %s", err) + } + } + if d.HasChange("tags") { o, n := d.GetChange("tags") diff --git a/aws/resource_aws_networkmanager_site.go b/aws/resource_aws_networkmanager_site.go index 2d8b57cc956..1d4f31ad780 100644 --- a/aws/resource_aws_networkmanager_site.go +++ b/aws/resource_aws_networkmanager_site.go @@ -51,7 +51,6 @@ func resourceAwsNetworkManagerSite() *schema.Resource { "description": { Type: schema.TypeString, Optional: true, - ForceNew: true, }, "global_network_id": { Type: schema.TypeString, @@ -163,6 +162,20 @@ func resourceAwsNetworkManagerSiteRead(d *schema.ResourceData, meta interface{}) func resourceAwsNetworkManagerSiteUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn + if d.HasChange("description") || d.HasChange("location") { + request := &networkmanager.UpdateSiteInput{ + Description: aws.String(d.Get("description").(string)), + GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), + Location: expandNetworkManagerLocation(d.Get("location").([]interface{})), + SiteId: aws.String(d.Id()), + } + + _, err := conn.UpdateSite(request) + if err != nil { + return fmt.Errorf("Failure updating Network Manager Site (%s): %s", d.Id(), err) + } + } + if d.HasChange("tags") { o, n := d.GetChange("tags") From def17d4d17e68dd7cb2b16fb525797cce6c6d39d Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Fri, 15 May 2020 21:49:19 +0100 Subject: [PATCH 013/229] r/aws_networkmanager_global_network: retryable creation error for ValidationException --- ...resource_aws_networkmanager_global_network.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_networkmanager_global_network.go b/aws/resource_aws_networkmanager_global_network.go index a8efae3cb7e..63e146ad49c 100644 --- a/aws/resource_aws_networkmanager_global_network.go +++ b/aws/resource_aws_networkmanager_global_network.go @@ -49,7 +49,21 @@ func resourceAwsNetworkManagerGlobalNetworkCreate(d *schema.ResourceData, meta i } log.Printf("[DEBUG] Creating Network Manager Global Network: %s", input) - output, err := conn.CreateGlobalNetwork(input) + var output *networkmanager.CreateGlobalNetworkOutput + err := resource.Retry(1*time.Minute, func() *resource.RetryError { + var err error + output, err = conn.CreateGlobalNetwork(input) + if err != nil { + if isAWSErr(err, "ValidationException", "Resource already exists with ID") { + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + if isResourceTimeoutError(err) { + output, err = conn.CreateGlobalNetwork(input) + } if err != nil { return fmt.Errorf("error creating Network Manager Global Network: %s", err) } From 93c27346a5d552df42494ea2598b357f0c799a19 Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Sat, 16 May 2020 19:46:52 +0100 Subject: [PATCH 014/229] d/aws_networkmanager_global_network: configuration & tests Output from acceptance test: $ make testacc TEST=./aws TESTARGS='-run=TestAccDataSourceAWSNetworkManager' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccDataSourceAWSNetworkManager -timeout 120m === RUN TestAccDataSourceAWSNetworkManagerGlobalNetwork === PAUSE TestAccDataSourceAWSNetworkManagerGlobalNetwork === CONT TestAccDataSourceAWSNetworkManagerGlobalNetwork --- PASS: TestAccDataSourceAWSNetworkManagerGlobalNetwork (45.09s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 46.280s --- ...ource_aws_networkmanager_global_network.go | 101 ++++++++++++++++++ ..._aws_networkmanager_global_network_test.go | 70 ++++++++++++ aws/provider.go | 1 + 3 files changed, 172 insertions(+) create mode 100644 aws/data_source_aws_networkmanager_global_network.go create mode 100644 aws/data_source_aws_networkmanager_global_network_test.go diff --git a/aws/data_source_aws_networkmanager_global_network.go b/aws/data_source_aws_networkmanager_global_network.go new file mode 100644 index 00000000000..608e8e37e32 --- /dev/null +++ b/aws/data_source_aws_networkmanager_global_network.go @@ -0,0 +1,101 @@ +package aws + +import ( + "errors" + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" +) + +func dataSourceAwsNetworkManagerGlobalNetwork() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsNetworkManagerGlobalNetworkRead, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeString, + Optional: true, + }, + "tags": tagsSchemaComputed(), + }, + } +} + +func dataSourceAwsNetworkManagerGlobalNetworkRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + + input := &networkmanager.DescribeGlobalNetworksInput{} + + if v, ok := d.GetOk("id"); ok { + input.GlobalNetworkIds = aws.StringSlice([]string{v.(string)}) + } + + log.Printf("[DEBUG] Reading Network Manager Global Network: %s", input) + output, err := conn.DescribeGlobalNetworks(input) + + if err != nil { + return fmt.Errorf("error reading Network Manager Global Network: %s", err) + } + + // do filtering here + var filteredGlobalNetworks []*networkmanager.GlobalNetwork + if tags, ok := d.GetOk("tags"); ok { + for _, globalNetwork := range output.GlobalNetworks { + tagsMatch := true + for key, val := range keyvaluetags.New(tags.(map[string]interface{})).Map() { + if v, ok := keyvaluetags.NetworkmanagerKeyValueTags(globalNetwork.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()[key]; ok { + if v != val { + tagsMatch = false + break + } + } else { + tagsMatch = false + break + } + } + if tagsMatch { + filteredGlobalNetworks = append(filteredGlobalNetworks, globalNetwork) + } + } + } else { + filteredGlobalNetworks = output.GlobalNetworks + } + + if output == nil || len(filteredGlobalNetworks) == 0 { + return errors.New("error reading Network Manager Global Network: no results found") + } + + if len(filteredGlobalNetworks) > 1 { + return errors.New("error reading Network Manager Global Network: more than one result found. Please try a more specific search criteria.") + } + + globalNetwork := filteredGlobalNetworks[0] + + if globalNetwork == nil { + return errors.New("error reading Network Manager Global Network: empty result") + } + + d.Set("description", globalNetwork.Description) + d.Set("arn", globalNetwork.GlobalNetworkArn) + + if err := d.Set("tags", keyvaluetags.NetworkmanagerKeyValueTags(globalNetwork.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %s", err) + } + + d.SetId(aws.StringValue(globalNetwork.GlobalNetworkId)) + + return nil +} diff --git a/aws/data_source_aws_networkmanager_global_network_test.go b/aws/data_source_aws_networkmanager_global_network_test.go new file mode 100644 index 00000000000..34dd0b4c0bf --- /dev/null +++ b/aws/data_source_aws_networkmanager_global_network_test.go @@ -0,0 +1,70 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccDataSourceAWSNetworkManagerGlobalNetwork(t *testing.T) { + dataSourceByIdName := "data.aws_networkmanager_global_network.test_by_id" + dataSourceByTagsName := "data.aws_networkmanager_global_network.test_by_tags" + resourceName := "aws_networkmanager_global_network.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsNetworkManagerGlobalNetworkDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsNetworkManagerGlobalNetworkConfig(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrPair(dataSourceByIdName, "id", resourceName, "id"), + resource.TestCheckResourceAttrPair(dataSourceByIdName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(dataSourceByIdName, "description", resourceName, "description"), + resource.TestCheckResourceAttrPair(dataSourceByIdName, "tags.Name", resourceName, "tags.Name"), + resource.TestCheckResourceAttrPair(dataSourceByIdName, "tags.OtherTag", resourceName, "tags.OtherTag"), + resource.TestCheckResourceAttrPair(dataSourceByTagsName, "id", resourceName, "id"), + resource.TestCheckResourceAttrPair(dataSourceByTagsName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(dataSourceByTagsName, "description", resourceName, "description"), + resource.TestCheckResourceAttrPair(dataSourceByTagsName, "tags.Name", resourceName, "tags.Name"), + ), + }, + }, + }) +} + +func testAccDataSourceAwsNetworkManagerGlobalNetworkConfig() string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = "test" + + tags = { + Name = "terraform-testacc-global-network-%d" + OtherTag = "some-value" + } +} + +resource "aws_networkmanager_global_network" "test2" { + description = "test2" + + tags = { + Name = "terraform-testacc-global-network2" + } +} + +data "aws_networkmanager_global_network" "test_by_id" { + id = "${aws_networkmanager_global_network.test.id}" +} + +data "aws_networkmanager_global_network" "test_by_tags" { + tags = { + Name = "${aws_networkmanager_global_network.test.tags["Name"]}" + } +} +`, acctest.RandInt()) +} diff --git a/aws/provider.go b/aws/provider.go index e54b7dc7e34..af549c08cbf 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -279,6 +279,7 @@ func Provider() terraform.ResourceProvider { "aws_network_acls": dataSourceAwsNetworkAcls(), "aws_network_interface": dataSourceAwsNetworkInterface(), "aws_network_interfaces": dataSourceAwsNetworkInterfaces(), + "aws_networkmanager_global_network": dataSourceAwsNetworkManagerGlobalNetwork(), "aws_organizations_organization": dataSourceAwsOrganizationsOrganization(), "aws_organizations_organizational_units": dataSourceAwsOrganizationsOrganizationalUnits(), "aws_partition": dataSourceAwsPartition(), From 9025d6b31021ed706a516c796f35a077d1d009fd Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Mon, 18 May 2020 11:43:02 +0100 Subject: [PATCH 015/229] d/aws_networkmanager_global_network: improved tag matching logic --- ...ata_source_aws_networkmanager_global_network.go | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/aws/data_source_aws_networkmanager_global_network.go b/aws/data_source_aws_networkmanager_global_network.go index 608e8e37e32..04b40267cf3 100644 --- a/aws/data_source_aws_networkmanager_global_network.go +++ b/aws/data_source_aws_networkmanager_global_network.go @@ -53,18 +53,12 @@ func dataSourceAwsNetworkManagerGlobalNetworkRead(d *schema.ResourceData, meta i // do filtering here var filteredGlobalNetworks []*networkmanager.GlobalNetwork if tags, ok := d.GetOk("tags"); ok { + keyValueTags := keyvaluetags.New(tags.(map[string]interface{})).IgnoreAws() for _, globalNetwork := range output.GlobalNetworks { tagsMatch := true - for key, val := range keyvaluetags.New(tags.(map[string]interface{})).Map() { - if v, ok := keyvaluetags.NetworkmanagerKeyValueTags(globalNetwork.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()[key]; ok { - if v != val { - tagsMatch = false - break - } - } else { - tagsMatch = false - break - } + if len(keyValueTags) > 0 { + listTags := keyvaluetags.NetworkmanagerKeyValueTags(globalNetwork.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + tagsMatch = listTags.ContainsAll(keyValueTags) } if tagsMatch { filteredGlobalNetworks = append(filteredGlobalNetworks, globalNetwork) From acbc6b9ca5a1c752c854f323a35107098ceb53b4 Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Mon, 18 May 2020 11:43:41 +0100 Subject: [PATCH 016/229] d/aws_networkmanager_site: configuration & tests Output from acceptance tests: $ make testacc TEST=./aws TESTARGS='-run=TestAccDataSourceAWSNetworkManagerSite' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccDataSourceAWSNetworkManagerSite -timeout 120m === RUN TestAccDataSourceAWSNetworkManagerSite === PAUSE TestAccDataSourceAWSNetworkManagerSite === CONT TestAccDataSourceAWSNetworkManagerSite --- PASS: TestAccDataSourceAWSNetworkManagerSite (44.82s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 45.806s --- aws/data_source_aws_networkmanager_site.go | 123 ++++++++++++++++++ ...ata_source_aws_networkmanager_site_test.go | 84 ++++++++++++ aws/provider.go | 1 + 3 files changed, 208 insertions(+) create mode 100644 aws/data_source_aws_networkmanager_site.go create mode 100644 aws/data_source_aws_networkmanager_site_test.go diff --git a/aws/data_source_aws_networkmanager_site.go b/aws/data_source_aws_networkmanager_site.go new file mode 100644 index 00000000000..655d869669e --- /dev/null +++ b/aws/data_source_aws_networkmanager_site.go @@ -0,0 +1,123 @@ +package aws + +import ( + "errors" + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" +) + +func dataSourceAwsNetworkManagerSite() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsNetworkManagerSiteRead, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "global_network_id": { + Type: schema.TypeString, + Required: true, + }, + "id": { + Type: schema.TypeString, + Optional: true, + }, + "location": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Optional: true, + }, + "latitude": { + Type: schema.TypeString, + Optional: true, + }, + "longitude": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "tags": tagsSchemaComputed(), + }, + } +} + +func dataSourceAwsNetworkManagerSiteRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + + input := &networkmanager.GetSitesInput{ + GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), + } + + if v, ok := d.GetOk("id"); ok { + input.SiteIds = aws.StringSlice([]string{v.(string)}) + } + + log.Printf("[DEBUG] Reading Network Manager Site: %s", input) + output, err := conn.GetSites(input) + + if err != nil { + return fmt.Errorf("error reading Network Manager Site: %s", err) + } + + // do filtering here + var filteredSites []*networkmanager.Site + if tags, ok := d.GetOk("tags"); ok { + keyValueTags := keyvaluetags.New(tags.(map[string]interface{})).IgnoreAws() + for _, site := range output.Sites { + tagsMatch := true + if len(keyValueTags) > 0 { + listTags := keyvaluetags.NetworkmanagerKeyValueTags(site.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + tagsMatch = listTags.ContainsAll(keyValueTags) + } + if tagsMatch { + filteredSites = append(filteredSites, site) + } + } + } else { + filteredSites = output.Sites + } + + if output == nil || len(filteredSites) == 0 { + return errors.New("error reading Network Manager Site: no results found") + } + + if len(filteredSites) > 1 { + return errors.New("error reading Network Manager Site: more than one result found. Please try a more specific search criteria.") + } + + site := filteredSites[0] + + if site == nil { + return errors.New("error reading Network Manager Site: empty result") + } + + d.Set("description", site.Description) + d.Set("arn", site.SiteArn) + if err := d.Set("location", flattenNetworkManagerLocation(site.Location)); err != nil { + return fmt.Errorf("error setting location: %s", err) + } + if err := d.Set("tags", keyvaluetags.NetworkmanagerKeyValueTags(site.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %s", err) + } + + d.SetId(aws.StringValue(site.SiteId)) + + return nil +} diff --git a/aws/data_source_aws_networkmanager_site_test.go b/aws/data_source_aws_networkmanager_site_test.go new file mode 100644 index 00000000000..e438ed92538 --- /dev/null +++ b/aws/data_source_aws_networkmanager_site_test.go @@ -0,0 +1,84 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccDataSourceAWSNetworkManagerSite(t *testing.T) { + dataSourceName := "data.aws_networkmanager_site.test" + dataSourceByIdName := "data.aws_networkmanager_site.test_by_id" + dataSourceByTagsName := "data.aws_networkmanager_site.test_by_tags" + resourceName := "aws_networkmanager_site.test" + resourceGlobalNetworkName := "aws_networkmanager_global_network.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsNetworkManagerSiteDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsNetworkManagerSiteConfig(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrPair(dataSourceName, "id", resourceName, "id"), + resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(dataSourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttrPair(dataSourceName, "global_network_id", resourceGlobalNetworkName, "id"), + resource.TestCheckResourceAttrPair(dataSourceName, "tags.Name", resourceName, "tags.Name"), + resource.TestCheckResourceAttrPair(dataSourceName, "tags.OtherTag", resourceName, "tags.OtherTag"), + resource.TestCheckResourceAttr(dataSourceName, "location.#", "1"), + resource.TestCheckResourceAttr(dataSourceName, "location.0.address", ""), + resource.TestCheckResourceAttr(dataSourceName, "location.0.latitude", "18.0029784"), + resource.TestCheckResourceAttr(dataSourceName, "location.0.longitude", "-76.7897987"), + resource.TestCheckResourceAttrPair(dataSourceByIdName, "id", resourceName, "id"), + resource.TestCheckResourceAttrPair(dataSourceByTagsName, "tags.Name", resourceName, "tags.Name"), + ), + }, + }, + }) +} + +func testAccDataSourceAwsNetworkManagerSiteConfig() string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = "test" +} + +resource "aws_networkmanager_site" "test" { + description = "test" + global_network_id = "${aws_networkmanager_global_network.test.id}" + + location { + latitude = "18.0029784" + longitude = "-76.7897987" + } + + tags = { + Name = "terraform-testacc-site-%d" + OtherTag = "some-value" + } +} + +data "aws_networkmanager_site" "test" { + global_network_id = "${aws_networkmanager_site.test.global_network_id}" +} + +data "aws_networkmanager_site" "test_by_id" { + global_network_id = "${aws_networkmanager_global_network.test.id}" + id = "${aws_networkmanager_site.test.id}" +} + +data "aws_networkmanager_site" "test_by_tags" { + global_network_id = "${aws_networkmanager_global_network.test.id}" + + tags = { + Name = "${aws_networkmanager_site.test.tags["Name"]}" + } +} +`, acctest.RandInt()) +} diff --git a/aws/provider.go b/aws/provider.go index af549c08cbf..6702d3537f6 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -280,6 +280,7 @@ func Provider() terraform.ResourceProvider { "aws_network_interface": dataSourceAwsNetworkInterface(), "aws_network_interfaces": dataSourceAwsNetworkInterfaces(), "aws_networkmanager_global_network": dataSourceAwsNetworkManagerGlobalNetwork(), + "aws_networkmanager_site": dataSourceAwsNetworkManagerSite(), "aws_organizations_organization": dataSourceAwsOrganizationsOrganization(), "aws_organizations_organizational_units": dataSourceAwsOrganizationsOrganizationalUnits(), "aws_partition": dataSourceAwsPartition(), From b215bb0109e6b6470d31c3c1cf06c9782c80cbbe Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Mon, 18 May 2020 17:12:59 +0100 Subject: [PATCH 017/229] d/aws_networkmanager_device: configuration & tests Output from acceptance test: $ make testacc TEST=./aws TESTARGS='-run=TestAccDataSourceAWSNetworkManagerDevice' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccDataSourceAWSNetworkManagerDevice -timeout 120m === RUN TestAccDataSourceAWSNetworkManagerDevice === PAUSE TestAccDataSourceAWSNetworkManagerDevice === CONT TestAccDataSourceAWSNetworkManagerDevice --- PASS: TestAccDataSourceAWSNetworkManagerDevice (62.20s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 63.223s --- aws/data_source_aws_networkmanager_device.go | 153 ++++++++++++++++++ ...a_source_aws_networkmanager_device_test.go | 108 +++++++++++++ aws/provider.go | 1 + 3 files changed, 262 insertions(+) create mode 100644 aws/data_source_aws_networkmanager_device.go create mode 100644 aws/data_source_aws_networkmanager_device_test.go diff --git a/aws/data_source_aws_networkmanager_device.go b/aws/data_source_aws_networkmanager_device.go new file mode 100644 index 00000000000..35d2ee82a5a --- /dev/null +++ b/aws/data_source_aws_networkmanager_device.go @@ -0,0 +1,153 @@ +package aws + +import ( + "errors" + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" +) + +func dataSourceAwsNetworkManagerDevice() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsNetworkManagerDeviceRead, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "global_network_id": { + Type: schema.TypeString, + Required: true, + }, + "id": { + Type: schema.TypeString, + Optional: true, + }, + "location": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "address": { + Type: schema.TypeString, + Optional: true, + }, + "latitude": { + Type: schema.TypeString, + Optional: true, + }, + "longitude": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "model": { + Type: schema.TypeString, + Computed: true, + }, + "serial_number": { + Type: schema.TypeString, + Computed: true, + }, + "site_id": { + Type: schema.TypeString, + Optional: true, + }, + "tags": tagsSchemaComputed(), + "type": { + Type: schema.TypeString, + Computed: true, + }, + "vendor": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourceAwsNetworkManagerDeviceRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).networkmanagerconn + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + + input := &networkmanager.GetDevicesInput{ + GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), + } + + if v, ok := d.GetOk("id"); ok { + input.DeviceIds = aws.StringSlice([]string{v.(string)}) + } + + if v, ok := d.GetOk("site_id"); ok { + input.SiteId = aws.String(v.(string)) + } + + log.Printf("[DEBUG] Reading Network Manager Device: %s", input) + output, err := conn.GetDevices(input) + + if err != nil { + return fmt.Errorf("error reading Network Manager Device: %s", err) + } + + // do filtering here + var filteredDevices []*networkmanager.Device + if tags, ok := d.GetOk("tags"); ok { + keyValueTags := keyvaluetags.New(tags.(map[string]interface{})).IgnoreAws() + for _, device := range output.Devices { + tagsMatch := true + if len(keyValueTags) > 0 { + listTags := keyvaluetags.NetworkmanagerKeyValueTags(device.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + tagsMatch = listTags.ContainsAll(keyValueTags) + } + if tagsMatch { + filteredDevices = append(filteredDevices, device) + } + } + } else { + filteredDevices = output.Devices + } + + if output == nil || len(filteredDevices) == 0 { + return errors.New("error reading Network Manager Device: no results found") + } + + if len(filteredDevices) > 1 { + return errors.New("error reading Network Manager Device: more than one result found. Please try a more specific search criteria.") + } + + device := filteredDevices[0] + + if device == nil { + return errors.New("error reading Network Manager Device: empty result") + } + + d.Set("arn", device.DeviceArn) + d.Set("description", device.Description) + d.Set("model", device.Model) + d.Set("serial_number", device.SerialNumber) + d.Set("site_id", device.SiteId) + d.Set("type", device.Type) + d.Set("vendor", device.Vendor) + + if err := d.Set("location", flattenNetworkManagerLocation(device.Location)); err != nil { + return fmt.Errorf("error setting location: %s", err) + } + if err := d.Set("tags", keyvaluetags.NetworkmanagerKeyValueTags(device.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %s", err) + } + + d.SetId(aws.StringValue(device.DeviceId)) + + return nil +} diff --git a/aws/data_source_aws_networkmanager_device_test.go b/aws/data_source_aws_networkmanager_device_test.go new file mode 100644 index 00000000000..cb2f021831b --- /dev/null +++ b/aws/data_source_aws_networkmanager_device_test.go @@ -0,0 +1,108 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccDataSourceAWSNetworkManagerDevice(t *testing.T) { + dataSourceName := "data.aws_networkmanager_device.test" + dataSourceByIdName := "data.aws_networkmanager_device.test_by_id" + dataSourceBySiteIdName := "data.aws_networkmanager_device.test_by_site_id" + dataSourceByTagsName := "data.aws_networkmanager_device.test_by_tags" + resourceName := "aws_networkmanager_device.test" + resourceSiteName := "aws_networkmanager_site.test" + resourceGlobalNetworkName := "aws_networkmanager_global_network.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsNetworkManagerDeviceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsNetworkManagerDeviceConfig(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrPair(dataSourceName, "id", resourceName, "id"), + resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(dataSourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttrPair(dataSourceName, "global_network_id", resourceGlobalNetworkName, "id"), + resource.TestCheckResourceAttrPair(dataSourceName, "model", resourceName, "model"), + resource.TestCheckResourceAttrPair(dataSourceName, "serial_number", resourceName, "serial_number"), + resource.TestCheckResourceAttrPair(dataSourceName, "site_id", resourceSiteName, "id"), + resource.TestCheckResourceAttrPair(dataSourceName, "type", resourceName, "type"), + resource.TestCheckResourceAttrPair(dataSourceName, "vendor", resourceName, "vendor"), + resource.TestCheckResourceAttrPair(dataSourceName, "tags.Name", resourceName, "tags.Name"), + resource.TestCheckResourceAttrPair(dataSourceName, "tags.OtherTag", resourceName, "tags.OtherTag"), + resource.TestCheckResourceAttr(dataSourceName, "location.#", "1"), + resource.TestCheckResourceAttr(dataSourceName, "location.0.address", ""), + resource.TestCheckResourceAttr(dataSourceName, "location.0.latitude", "18.0029784"), + resource.TestCheckResourceAttr(dataSourceName, "location.0.longitude", "-76.7897987"), + resource.TestCheckResourceAttrPair(dataSourceByIdName, "id", resourceName, "id"), + resource.TestCheckResourceAttrPair(dataSourceBySiteIdName, "site_id", resourceSiteName, "id"), + resource.TestCheckResourceAttrPair(dataSourceByTagsName, "tags.Name", resourceName, "tags.Name"), + ), + }, + }, + }) +} + +func testAccDataSourceAwsNetworkManagerDeviceConfig() string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = "test" +} + +resource "aws_networkmanager_site" "test" { + description = "test" + global_network_id = "${aws_networkmanager_global_network.test.id}" + +} + +resource "aws_networkmanager_device" "test" { + description = "test" + global_network_id = "${aws_networkmanager_global_network.test.id}" + site_id = "${aws_networkmanager_site.test.id}" + model = "abc" + serial_number = "123" + type = "office device" + vendor = "company" + + location { + latitude = "18.0029784" + longitude = "-76.7897987" + } + + tags = { + Name = "terraform-testacc-site-%d" + OtherTag = "some-value" + } +} + +data "aws_networkmanager_device" "test" { + global_network_id = "${aws_networkmanager_device.test.global_network_id}" +} + +data "aws_networkmanager_device" "test_by_id" { + global_network_id = "${aws_networkmanager_global_network.test.id}" + id = "${aws_networkmanager_device.test.id}" +} + +data "aws_networkmanager_device" "test_by_site_id" { + global_network_id = "${aws_networkmanager_device.test.global_network_id}" + site_id = "${aws_networkmanager_site.test.id}" +} + +data "aws_networkmanager_device" "test_by_tags" { + global_network_id = "${aws_networkmanager_global_network.test.id}" + + tags = { + Name = "${aws_networkmanager_device.test.tags["Name"]}" + } +} +`, acctest.RandInt()) +} diff --git a/aws/provider.go b/aws/provider.go index 6702d3537f6..6f028b8b7af 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -279,6 +279,7 @@ func Provider() terraform.ResourceProvider { "aws_network_acls": dataSourceAwsNetworkAcls(), "aws_network_interface": dataSourceAwsNetworkInterface(), "aws_network_interfaces": dataSourceAwsNetworkInterfaces(), + "aws_networkmanager_device": dataSourceAwsNetworkManagerDevice(), "aws_networkmanager_global_network": dataSourceAwsNetworkManagerGlobalNetwork(), "aws_networkmanager_site": dataSourceAwsNetworkManagerSite(), "aws_organizations_organization": dataSourceAwsOrganizationsOrganization(), From 3c87bee1f648a3c16e615f90d7944d987e3ecf98 Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Thu, 10 Sep 2020 23:46:58 +0100 Subject: [PATCH 018/229] networkmanager support Terraform Plugin SDK V2 --- aws/data_source_aws_networkmanager_device.go | 2 +- aws/data_source_aws_networkmanager_device_test.go | 4 ++-- aws/data_source_aws_networkmanager_global_network.go | 2 +- ...data_source_aws_networkmanager_global_network_test.go | 4 ++-- aws/data_source_aws_networkmanager_site.go | 2 +- aws/data_source_aws_networkmanager_site_test.go | 4 ++-- aws/resource_aws_networkmanager_device.go | 4 ++-- aws/resource_aws_networkmanager_device_test.go | 4 ++-- aws/resource_aws_networkmanager_global_network.go | 4 ++-- aws/resource_aws_networkmanager_global_network_test.go | 4 ++-- aws/resource_aws_networkmanager_site.go | 4 ++-- aws/resource_aws_networkmanager_site_test.go | 4 ++-- ...ce_aws_networkmanager_transit_gateway_registration.go | 4 ++-- ...s_networkmanager_transit_gateway_registration_test.go | 9 +++++---- 14 files changed, 28 insertions(+), 27 deletions(-) diff --git a/aws/data_source_aws_networkmanager_device.go b/aws/data_source_aws_networkmanager_device.go index 35d2ee82a5a..7923910030b 100644 --- a/aws/data_source_aws_networkmanager_device.go +++ b/aws/data_source_aws_networkmanager_device.go @@ -7,7 +7,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) diff --git a/aws/data_source_aws_networkmanager_device_test.go b/aws/data_source_aws_networkmanager_device_test.go index cb2f021831b..1811f1c516b 100644 --- a/aws/data_source_aws_networkmanager_device_test.go +++ b/aws/data_source_aws_networkmanager_device_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) func TestAccDataSourceAWSNetworkManagerDevice(t *testing.T) { diff --git a/aws/data_source_aws_networkmanager_global_network.go b/aws/data_source_aws_networkmanager_global_network.go index 04b40267cf3..cfb6eaac4ed 100644 --- a/aws/data_source_aws_networkmanager_global_network.go +++ b/aws/data_source_aws_networkmanager_global_network.go @@ -7,7 +7,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) diff --git a/aws/data_source_aws_networkmanager_global_network_test.go b/aws/data_source_aws_networkmanager_global_network_test.go index 34dd0b4c0bf..73f348d4b91 100644 --- a/aws/data_source_aws_networkmanager_global_network_test.go +++ b/aws/data_source_aws_networkmanager_global_network_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) func TestAccDataSourceAWSNetworkManagerGlobalNetwork(t *testing.T) { diff --git a/aws/data_source_aws_networkmanager_site.go b/aws/data_source_aws_networkmanager_site.go index 655d869669e..95337e6fd7d 100644 --- a/aws/data_source_aws_networkmanager_site.go +++ b/aws/data_source_aws_networkmanager_site.go @@ -7,7 +7,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) diff --git a/aws/data_source_aws_networkmanager_site_test.go b/aws/data_source_aws_networkmanager_site_test.go index e438ed92538..a3443cd3d20 100644 --- a/aws/data_source_aws_networkmanager_site_test.go +++ b/aws/data_source_aws_networkmanager_site_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) func TestAccDataSourceAWSNetworkManagerSite(t *testing.T) { diff --git a/aws/resource_aws_networkmanager_device.go b/aws/resource_aws_networkmanager_device.go index afaa263516c..b730a25db17 100644 --- a/aws/resource_aws_networkmanager_device.go +++ b/aws/resource_aws_networkmanager_device.go @@ -9,8 +9,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) diff --git a/aws/resource_aws_networkmanager_device_test.go b/aws/resource_aws_networkmanager_device_test.go index 1ca1912e41c..995bc9395d1 100644 --- a/aws/resource_aws_networkmanager_device_test.go +++ b/aws/resource_aws_networkmanager_device_test.go @@ -8,8 +8,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" "github.com/hashicorp/go-multierror" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) func init() { diff --git a/aws/resource_aws_networkmanager_global_network.go b/aws/resource_aws_networkmanager_global_network.go index 63e146ad49c..ea83de6a5df 100644 --- a/aws/resource_aws_networkmanager_global_network.go +++ b/aws/resource_aws_networkmanager_global_network.go @@ -7,8 +7,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) diff --git a/aws/resource_aws_networkmanager_global_network_test.go b/aws/resource_aws_networkmanager_global_network_test.go index 5ad89e4c4db..5c4427acc64 100644 --- a/aws/resource_aws_networkmanager_global_network_test.go +++ b/aws/resource_aws_networkmanager_global_network_test.go @@ -9,8 +9,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" "github.com/hashicorp/go-multierror" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) func init() { diff --git a/aws/resource_aws_networkmanager_site.go b/aws/resource_aws_networkmanager_site.go index 1d4f31ad780..e206a4dc09e 100644 --- a/aws/resource_aws_networkmanager_site.go +++ b/aws/resource_aws_networkmanager_site.go @@ -9,8 +9,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) diff --git a/aws/resource_aws_networkmanager_site_test.go b/aws/resource_aws_networkmanager_site_test.go index 8714ba63b50..a5e4ae5dc8b 100644 --- a/aws/resource_aws_networkmanager_site_test.go +++ b/aws/resource_aws_networkmanager_site_test.go @@ -8,8 +8,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" "github.com/hashicorp/go-multierror" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) func init() { diff --git a/aws/resource_aws_networkmanager_transit_gateway_registration.go b/aws/resource_aws_networkmanager_transit_gateway_registration.go index 0be56924a58..d535a23717e 100644 --- a/aws/resource_aws_networkmanager_transit_gateway_registration.go +++ b/aws/resource_aws_networkmanager_transit_gateway_registration.go @@ -9,8 +9,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func resourceAwsNetworkManagerTransitGatewayRegistration() *schema.Resource { diff --git a/aws/resource_aws_networkmanager_transit_gateway_registration_test.go b/aws/resource_aws_networkmanager_transit_gateway_registration_test.go index f83f36b03e2..655cf8ed7e6 100644 --- a/aws/resource_aws_networkmanager_transit_gateway_registration_test.go +++ b/aws/resource_aws_networkmanager_transit_gateway_registration_test.go @@ -2,13 +2,14 @@ package aws import ( "fmt" + "log" + "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" "github.com/hashicorp/go-multierror" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" - "log" - "testing" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) func init() { From 19afb9b5e17fa5d79b35edf177666d32716aa606 Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Fri, 11 Sep 2020 00:18:57 +0100 Subject: [PATCH 019/229] networkmanager: Update test configuration to 0.12 syntax. Action Required: Terraform 0.12 Syntax #8950 AT003: acceptance test function name should include underscore --- ...a_source_aws_networkmanager_device_test.go | 22 ++++++++--------- ..._aws_networkmanager_global_network_test.go | 6 ++--- ...ata_source_aws_networkmanager_site_test.go | 14 +++++------ ...resource_aws_networkmanager_device_test.go | 24 +++++++++---------- aws/resource_aws_networkmanager_site_test.go | 8 +++---- ...nager_transit_gateway_registration_test.go | 8 +++---- 6 files changed, 41 insertions(+), 41 deletions(-) diff --git a/aws/data_source_aws_networkmanager_device_test.go b/aws/data_source_aws_networkmanager_device_test.go index 1811f1c516b..94cd621cff5 100644 --- a/aws/data_source_aws_networkmanager_device_test.go +++ b/aws/data_source_aws_networkmanager_device_test.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) -func TestAccDataSourceAWSNetworkManagerDevice(t *testing.T) { +func TestAccDataSourceAWSNetworkManagerDevice_basic(t *testing.T) { dataSourceName := "data.aws_networkmanager_device.test" dataSourceByIdName := "data.aws_networkmanager_device.test_by_id" dataSourceBySiteIdName := "data.aws_networkmanager_device.test_by_site_id" @@ -59,14 +59,14 @@ resource "aws_networkmanager_global_network" "test" { resource "aws_networkmanager_site" "test" { description = "test" - global_network_id = "${aws_networkmanager_global_network.test.id}" + global_network_id = aws_networkmanager_global_network.test.id } resource "aws_networkmanager_device" "test" { description = "test" - global_network_id = "${aws_networkmanager_global_network.test.id}" - site_id = "${aws_networkmanager_site.test.id}" + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id model = "abc" serial_number = "123" type = "office device" @@ -84,24 +84,24 @@ resource "aws_networkmanager_device" "test" { } data "aws_networkmanager_device" "test" { - global_network_id = "${aws_networkmanager_device.test.global_network_id}" + global_network_id = aws_networkmanager_device.test.global_network_id } data "aws_networkmanager_device" "test_by_id" { - global_network_id = "${aws_networkmanager_global_network.test.id}" - id = "${aws_networkmanager_device.test.id}" + global_network_id = aws_networkmanager_global_network.test.id + id = aws_networkmanager_device.test.id } data "aws_networkmanager_device" "test_by_site_id" { - global_network_id = "${aws_networkmanager_device.test.global_network_id}" - site_id = "${aws_networkmanager_site.test.id}" + global_network_id = aws_networkmanager_device.test.global_network_id + site_id = aws_networkmanager_site.test.id } data "aws_networkmanager_device" "test_by_tags" { - global_network_id = "${aws_networkmanager_global_network.test.id}" + global_network_id = aws_networkmanager_global_network.test.id tags = { - Name = "${aws_networkmanager_device.test.tags["Name"]}" + Name = aws_networkmanager_device.test.tags["Name"] } } `, acctest.RandInt()) diff --git a/aws/data_source_aws_networkmanager_global_network_test.go b/aws/data_source_aws_networkmanager_global_network_test.go index 73f348d4b91..77b6941cc64 100644 --- a/aws/data_source_aws_networkmanager_global_network_test.go +++ b/aws/data_source_aws_networkmanager_global_network_test.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) -func TestAccDataSourceAWSNetworkManagerGlobalNetwork(t *testing.T) { +func TestAccDataSourceAWSNetworkManagerGlobalNetwork_basic(t *testing.T) { dataSourceByIdName := "data.aws_networkmanager_global_network.test_by_id" dataSourceByTagsName := "data.aws_networkmanager_global_network.test_by_tags" resourceName := "aws_networkmanager_global_network.test" @@ -58,12 +58,12 @@ resource "aws_networkmanager_global_network" "test2" { } data "aws_networkmanager_global_network" "test_by_id" { - id = "${aws_networkmanager_global_network.test.id}" + id = aws_networkmanager_global_network.test.id } data "aws_networkmanager_global_network" "test_by_tags" { tags = { - Name = "${aws_networkmanager_global_network.test.tags["Name"]}" + Name = aws_networkmanager_global_network.test.tags["Name"] } } `, acctest.RandInt()) diff --git a/aws/data_source_aws_networkmanager_site_test.go b/aws/data_source_aws_networkmanager_site_test.go index a3443cd3d20..cc5e064090f 100644 --- a/aws/data_source_aws_networkmanager_site_test.go +++ b/aws/data_source_aws_networkmanager_site_test.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) -func TestAccDataSourceAWSNetworkManagerSite(t *testing.T) { +func TestAccDataSourceAWSNetworkManagerSite_basic(t *testing.T) { dataSourceName := "data.aws_networkmanager_site.test" dataSourceByIdName := "data.aws_networkmanager_site.test_by_id" dataSourceByTagsName := "data.aws_networkmanager_site.test_by_tags" @@ -51,7 +51,7 @@ resource "aws_networkmanager_global_network" "test" { resource "aws_networkmanager_site" "test" { description = "test" - global_network_id = "${aws_networkmanager_global_network.test.id}" + global_network_id = aws_networkmanager_global_network.test.id location { latitude = "18.0029784" @@ -65,19 +65,19 @@ resource "aws_networkmanager_site" "test" { } data "aws_networkmanager_site" "test" { - global_network_id = "${aws_networkmanager_site.test.global_network_id}" + global_network_id = aws_networkmanager_site.test.global_network_id } data "aws_networkmanager_site" "test_by_id" { - global_network_id = "${aws_networkmanager_global_network.test.id}" - id = "${aws_networkmanager_site.test.id}" + global_network_id = aws_networkmanager_global_network.test.id + id = aws_networkmanager_site.test.id } data "aws_networkmanager_site" "test_by_tags" { - global_network_id = "${aws_networkmanager_global_network.test.id}" + global_network_id = aws_networkmanager_global_network.test.id tags = { - Name = "${aws_networkmanager_site.test.tags["Name"]}" + Name = aws_networkmanager_site.test.tags["Name"] } } `, acctest.RandInt()) diff --git a/aws/resource_aws_networkmanager_device_test.go b/aws/resource_aws_networkmanager_device_test.go index 995bc9395d1..a3c5e8433d3 100644 --- a/aws/resource_aws_networkmanager_device_test.go +++ b/aws/resource_aws_networkmanager_device_test.go @@ -234,13 +234,13 @@ resource "aws_networkmanager_global_network" "test" { resource "aws_networkmanager_site" "test" { description = "test" - global_network_id = "${aws_networkmanager_global_network.test.id}" + global_network_id = aws_networkmanager_global_network.test.id } resource "aws_networkmanager_device" "test" { description = %q - global_network_id = "${aws_networkmanager_global_network.test.id}" - site_id = "${aws_networkmanager_site.test.id}" + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id model = "abc" serial_number = "123" type = "office device" @@ -257,13 +257,13 @@ resource "aws_networkmanager_global_network" "test" { resource "aws_networkmanager_site" "test" { description = "test" - global_network_id = "${aws_networkmanager_global_network.test.id}" + global_network_id = aws_networkmanager_global_network.test.id } resource "aws_networkmanager_device" "test" { description = %q - global_network_id = "${aws_networkmanager_global_network.test.id}" - site_id = "${aws_networkmanager_site.test.id}" + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id tags = { %q = %q @@ -280,12 +280,12 @@ resource "aws_networkmanager_global_network" "test" { resource "aws_networkmanager_site" "test" { description = "test" - global_network_id = "${aws_networkmanager_global_network.test.id}" + global_network_id = aws_networkmanager_global_network.test.id } resource "aws_networkmanager_device" "test" { description = %q - global_network_id = "${aws_networkmanager_global_network.test.id}" + global_network_id = aws_networkmanager_global_network.test.id tags = { %q = %q @@ -303,18 +303,18 @@ resource "aws_networkmanager_global_network" "test" { resource "aws_networkmanager_site" "test" { description = "test" - global_network_id = "${aws_networkmanager_global_network.test.id}" + global_network_id = aws_networkmanager_global_network.test.id } resource "aws_networkmanager_site" "test2" { description = "test2" - global_network_id = "${aws_networkmanager_global_network.test.id}" + global_network_id = aws_networkmanager_global_network.test.id } resource "aws_networkmanager_device" "test" { description = %q - global_network_id = "${aws_networkmanager_global_network.test.id}" - site_id = "${aws_networkmanager_site.test2.id}" + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test2.id model = %q serial_number = %q type = %q diff --git a/aws/resource_aws_networkmanager_site_test.go b/aws/resource_aws_networkmanager_site_test.go index a5e4ae5dc8b..99ce64272bd 100644 --- a/aws/resource_aws_networkmanager_site_test.go +++ b/aws/resource_aws_networkmanager_site_test.go @@ -222,7 +222,7 @@ resource "aws_networkmanager_global_network" "test" { resource "aws_networkmanager_site" "test" { description = %q - global_network_id = "${aws_networkmanager_global_network.test.id}" + global_network_id = aws_networkmanager_global_network.test.id } `, description) } @@ -235,7 +235,7 @@ resource "aws_networkmanager_global_network" "test" { resource "aws_networkmanager_site" "test" { description = %q - global_network_id = "${aws_networkmanager_global_network.test.id}" + global_network_id = aws_networkmanager_global_network.test.id tags = { %q = %q @@ -252,7 +252,7 @@ resource "aws_networkmanager_global_network" "test" { resource "aws_networkmanager_site" "test" { description = %q - global_network_id = "${aws_networkmanager_global_network.test.id}" + global_network_id = aws_networkmanager_global_network.test.id tags = { %q = %q @@ -270,7 +270,7 @@ resource "aws_networkmanager_global_network" "test" { resource "aws_networkmanager_site" "test" { description = %q - global_network_id = "${aws_networkmanager_global_network.test.id}" + global_network_id = aws_networkmanager_global_network.test.id location { latitude = %q diff --git a/aws/resource_aws_networkmanager_transit_gateway_registration_test.go b/aws/resource_aws_networkmanager_transit_gateway_registration_test.go index 655cf8ed7e6..afc2a55dd74 100644 --- a/aws/resource_aws_networkmanager_transit_gateway_registration_test.go +++ b/aws/resource_aws_networkmanager_transit_gateway_registration_test.go @@ -146,8 +146,8 @@ resource "aws_networkmanager_global_network" "test" { } resource "aws_ec2_transit_gateway" "test" {} resource "aws_networkmanager_transit_gateway_registration" "test" { - global_network_id = "${aws_networkmanager_global_network.test.id}" - transit_gateway_arn = "${aws_ec2_transit_gateway.test.arn}" + global_network_id = aws_networkmanager_global_network.test.id + transit_gateway_arn = aws_ec2_transit_gateway.test.arn } ` } @@ -161,8 +161,8 @@ resource "aws_networkmanager_global_network" "test2" { } resource "aws_ec2_transit_gateway" "test" {} resource "aws_networkmanager_transit_gateway_registration" "test" { - global_network_id = "${aws_networkmanager_global_network.test2.id}" - transit_gateway_arn = "${aws_ec2_transit_gateway.test.arn}" + global_network_id = aws_networkmanager_global_network.test2.id + transit_gateway_arn = aws_ec2_transit_gateway.test.arn } ` } From fb40b151b885fcc049e69d87838a306ac56ff9f1 Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Fri, 11 Sep 2020 00:23:29 +0100 Subject: [PATCH 020/229] r/aws_networkmanager*: awsproviderlint fixes R005: multiple ResourceData.HasChange() calls can be combined with single HasChanges() call --- aws/resource_aws_networkmanager_device.go | 2 +- aws/resource_aws_networkmanager_site.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_networkmanager_device.go b/aws/resource_aws_networkmanager_device.go index b730a25db17..56a4a5ae7a5 100644 --- a/aws/resource_aws_networkmanager_device.go +++ b/aws/resource_aws_networkmanager_device.go @@ -192,7 +192,7 @@ func resourceAwsNetworkManagerDeviceRead(d *schema.ResourceData, meta interface{ func resourceAwsNetworkManagerDeviceUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn - if d.HasChange("description") || d.HasChange("location") || d.HasChange("model") || d.HasChange("serial_number") || d.HasChange("site_id") || d.HasChange("type") || d.HasChange("vendor") { + if d.HasChanges("description", "location", "model", "serial_number", "site_id", "type", "vendor") { request := &networkmanager.UpdateDeviceInput{ Description: aws.String(d.Get("description").(string)), DeviceId: aws.String(d.Id()), diff --git a/aws/resource_aws_networkmanager_site.go b/aws/resource_aws_networkmanager_site.go index e206a4dc09e..6969470ccc5 100644 --- a/aws/resource_aws_networkmanager_site.go +++ b/aws/resource_aws_networkmanager_site.go @@ -162,7 +162,7 @@ func resourceAwsNetworkManagerSiteRead(d *schema.ResourceData, meta interface{}) func resourceAwsNetworkManagerSiteUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn - if d.HasChange("description") || d.HasChange("location") { + if d.HasChanges("description", "location") { request := &networkmanager.UpdateSiteInput{ Description: aws.String(d.Get("description").(string)), GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), From 7c8ab53a56109b0be654f7693ab33106162c724a Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Fri, 11 Sep 2020 01:35:54 +0100 Subject: [PATCH 021/229] networkmanager: add resource and datasource docs website/docs/d/networkmanager_device.markdown website/docs/d/networkmanager_global_network.markdown website/docs/d/networkmanager_site.markdown website/docs/r/networkmanager_device.markdown website/docs/r/networkmanager_global_network.markdown website/docs/r/networkmanager_site.markdown website/docs/r/networkmanager_transit_gateway_registration.markdown --- website/docs/d/networkmanager_device.markdown | 47 ++++++++++++++ .../d/networkmanager_global_network.markdown | 33 ++++++++++ website/docs/d/networkmanager_site.markdown | 43 +++++++++++++ website/docs/r/networkmanager_device.markdown | 62 +++++++++++++++++++ .../r/networkmanager_global_network.markdown | 40 ++++++++++++ website/docs/r/networkmanager_site.markdown | 51 +++++++++++++++ ...ager_transit_gateway_registration.markdown | 43 +++++++++++++ 7 files changed, 319 insertions(+) create mode 100644 website/docs/d/networkmanager_device.markdown create mode 100644 website/docs/d/networkmanager_global_network.markdown create mode 100644 website/docs/d/networkmanager_site.markdown create mode 100644 website/docs/r/networkmanager_device.markdown create mode 100644 website/docs/r/networkmanager_global_network.markdown create mode 100644 website/docs/r/networkmanager_site.markdown create mode 100644 website/docs/r/networkmanager_transit_gateway_registration.markdown diff --git a/website/docs/d/networkmanager_device.markdown b/website/docs/d/networkmanager_device.markdown new file mode 100644 index 00000000000..1d2b3d39a0c --- /dev/null +++ b/website/docs/d/networkmanager_device.markdown @@ -0,0 +1,47 @@ +--- +subcategory: "Transit Gateway Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_device" +description: |- + Retrieve information about a device. +--- + +# Data Source: aws_networkmanager_device + +Retrieve information about a device. + +## Example Usage + +```hcl +data "aws_networkmanager_device" "example" { + id = var.global_network_id +} +``` + +## Argument Reference + +* `id` - (Optional) The id of the specific device to retrieve. + +* `global_network_id` - (Required) The ID of the Global Network of the device to retrieve. + +* `site_id` - (Optional) The ID of the Site of the device to retrieve. + +* `tags` - (Optional) A map of tags, each pair of which must exactly match + a pair on the desired device. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `description` - Description of the device. +* `location` - The device location as documented below. +* `type` - The type of device. +* `model` - The model of device. +* `serial_number` - The serial number of the device. +* `vendor` - The vendor of the device. + +The `location` object supports the following: + +* `address` - Address of the location. +* `latitude` - Latitude of the location. +* `longitude` - Longitude of the location. diff --git a/website/docs/d/networkmanager_global_network.markdown b/website/docs/d/networkmanager_global_network.markdown new file mode 100644 index 00000000000..16abc54870d --- /dev/null +++ b/website/docs/d/networkmanager_global_network.markdown @@ -0,0 +1,33 @@ +--- +subcategory: "Transit Gateway Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_global_network" +description: |- + Retrieve information about a global network. +--- + +# Data Source: aws_networkmanager_global_network + +Retrieve information about a global network. + +## Example Usage + +```hcl +data "aws_networkmanager_global_network" "example" { + id = var.global_network_id +} +``` + +## Argument Reference + +* `id` - (Optional) The id of the specific global network to retrieve. + +* `tags` - (Optional) A map of tags, each pair of which must exactly match + a pair on the desired global network. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - The ARN of the global network. +* `description` - The description of the global network. diff --git a/website/docs/d/networkmanager_site.markdown b/website/docs/d/networkmanager_site.markdown new file mode 100644 index 00000000000..ec5c239c899 --- /dev/null +++ b/website/docs/d/networkmanager_site.markdown @@ -0,0 +1,43 @@ +--- +subcategory: "Transit Gateway Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_site" +description: |- + Retrieve information about a site. +--- + +# Data Source: aws_networkmanager_site + +Retrieve information about a site. + +## Example Usage + +```hcl +data " aws_networkmanager_site" "example" { + id = var.global_network_id +} +``` + +## Argument Reference + +* `id` - (Optional) The id of the specific site to retrieve. + +* `global_network_id` - (Required) The ID of the Global Network of the site to retrieve. + +* `tags` - (Optional) A map of tags, each pair of which must exactly match + a pair on the desired site. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - The ARN of the site. +* `description` - The description of the site. +* `location` - The site location as documented below. +* `tags` - Key-value tags for the Site. + +The `location` object supports the following: + +* `address` - Address of the location. +* `latitude` - Latitude of the location. +* `longitude` - Longitude of the location. diff --git a/website/docs/r/networkmanager_device.markdown b/website/docs/r/networkmanager_device.markdown new file mode 100644 index 00000000000..fbdf012a358 --- /dev/null +++ b/website/docs/r/networkmanager_device.markdown @@ -0,0 +1,62 @@ +--- +subcategory: "Transit Gateway Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_device" +description: |- + Creates a device in a global network. +--- + +# Resource: aws_networkmanager_device + +Creates a device in a global network. If you specify both a site ID and a location, +the location of the site is used for visualization in the Network Manager console. + +## Example Usage + +```hcl +resource "aws_networkmanager_global_network" "example" { +} + +resource "aws_networkmanager_site" "example" { + global_network_id = aws_networkmanager_global_network.example.id +} + +resource "aws_networkmanager_device" "example" { + global_network_id = aws_networkmanager_global_network.example.id + site_id = aws_networkmanager_site.example.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `global_network_id` - (Required) The ID of the Global Network to create the device in. +* `description` - (Optional) Description of the device. +* `location` - (Optional) The device location as documented below. +* `type` - (Optional) The type of device. +* `model` - (Optional) The model of device. +* `serial_number` - (Optional) The serial number of the device. +* `site_id` - (Optional) The ID of the Site to create device in. +* `vendor` - (Optional) The vendor of the device. +* `tags` - (Optional) Key-value tags for the device. + +The `location` object supports the following: + +* `address` - (Optional) Address of the location. +* `latitude` - (Optional) Latitude of the location. +* `longitude` - (Optional) Longitude of the location. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - Device Amazon Resource Name (ARN) + +## Import + +`aws_networkmanager_device` can be imported using the device ARN, e.g. + +``` +$ terraform import aws_networkmanager_device.example arn:aws:networkmanager::123456789012:device/global-network-0d47f6t230mz46dy4/device-07f6fd08867abc123 +``` diff --git a/website/docs/r/networkmanager_global_network.markdown b/website/docs/r/networkmanager_global_network.markdown new file mode 100644 index 00000000000..c611f6f2067 --- /dev/null +++ b/website/docs/r/networkmanager_global_network.markdown @@ -0,0 +1,40 @@ +--- +subcategory: "Transit Gateway Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_global_network" +description: |- + Provides a global network resource. +--- + +# Resource: aws_networkmanager_global_network + +Provides a global network resource. + +## Example Usage + +```hcl +resource "aws_networkmanager_global_network" "example" { + description = "example" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `description` - (Optional) Description of the Global Network. +* `tags` - (Optional) Key-value tags for the Global Network. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - Global Network Amazon Resource Name (ARN) + +## Import + +`aws_networkmanager_global_network` can be imported using the global network ID, e.g. + +``` +$ terraform import aws_networkmanager_global_network.example global-network-0d47f6t230mz46dy4 +``` diff --git a/website/docs/r/networkmanager_site.markdown b/website/docs/r/networkmanager_site.markdown new file mode 100644 index 00000000000..b719836735e --- /dev/null +++ b/website/docs/r/networkmanager_site.markdown @@ -0,0 +1,51 @@ +--- +subcategory: "Transit Gateway Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_site" +description: |- + Creates a site in a global network. +--- + +# Resource: aws_networkmanager_site + +Creates a site in a global network. + +## Example Usage + +```hcl +resource "aws_networkmanager_global_network" "example" { +} + +resource "aws_networkmanager_site" "example" { + global_network_id = aws_networkmanager_global_network.example.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `global_network_id` - (Required) The ID of the Global Network to create the site in. +* `description` - (Optional) Description of the Site. +* `location` - (Optional) The site location as documented below. +* `tags` - (Optional) Key-value tags for the Site. + +The `location` object supports the following: + +* `address` - (Optional) Address of the location. +* `latitude` - (Optional) Latitude of the location. +* `longitude` - (Optional) Longitude of the location. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - Site Amazon Resource Name (ARN) + +## Import + +`aws_networkmanager_site` can be imported using the site ARN, e.g. + +``` +$ terraform import aws_networkmanager_site.example arn:aws:networkmanager::123456789012:site/global-network-0d47f6t230mz46dy4/site-444555aaabbb11223 +``` diff --git a/website/docs/r/networkmanager_transit_gateway_registration.markdown b/website/docs/r/networkmanager_transit_gateway_registration.markdown new file mode 100644 index 00000000000..f48c8fd5a04 --- /dev/null +++ b/website/docs/r/networkmanager_transit_gateway_registration.markdown @@ -0,0 +1,43 @@ +--- +subcategory: "Transit Gateway Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_transit_gateway_registration" +description: |- + Registers a transit gateway to a global network. +--- + +# Resource: aws_networkmanager_transit_gateway_registration + +Registers a transit gateway to a global network. The transit gateway can be in any AWS Region, +but it must be owned by the same AWS account that owns the global network. +You cannot register a transit gateway in more than one global network. + +## Example Usage + +```hcl +resource "aws_networkmanager_global_network" "example" { + description = "example" +} + +resource "aws_ec2_transit_gateway" "example" {} + +resource "aws_networkmanager_transit_gateway_registration" "example" { + global_network_id = aws_networkmanager_global_network.example.id + transit_gateway_arn = aws_ec2_transit_gateway.example.arn +} +``` + +## Argument Reference + +The following arguments are supported: + +* `global_network_id` - (Required) The ID of the Global Network to register to. +* `transit_gateway_arn` - (Required) The ARN of the Transit Gateway to register. + +## Import + +`aws_networkmanager_transit_gateway_registration` can be imported using the transit gateway ARN and the global network ID, e.g. + +``` +$ terraform import aws_networkmanager_transit_gateway_registration.example arn:aws:ec2:us-west-2:123456789012:transit-gateway/tgw-123abc05e04123abc,global-network-0d47f6t230mz46dy4 +``` From 173692b56a5462509ce40f31d344bcc463eb7a10 Mon Sep 17 00:00:00 2001 From: Mykola Ulianytskyi Date: Tue, 9 Mar 2021 18:21:25 +0200 Subject: [PATCH 022/229] r/aws_gamelift_game_server_group: New resource --- .../service/gamelift/waiter/status.go | 33 + .../service/gamelift/waiter/waiter.go | 51 + aws/provider.go | 1 + ...resource_aws_gamelift_game_server_group.go | 531 +++++++ ...rce_aws_gamelift_game_server_group_test.go | 1238 +++++++++++++++++ .../gamelift_game_server_group.html.markdown | 206 +++ 6 files changed, 2060 insertions(+) create mode 100644 aws/internal/service/gamelift/waiter/status.go create mode 100644 aws/internal/service/gamelift/waiter/waiter.go create mode 100644 aws/resource_aws_gamelift_game_server_group.go create mode 100644 aws/resource_aws_gamelift_game_server_group_test.go create mode 100644 website/docs/r/gamelift_game_server_group.html.markdown diff --git a/aws/internal/service/gamelift/waiter/status.go b/aws/internal/service/gamelift/waiter/status.go new file mode 100644 index 00000000000..99bfe16e2bf --- /dev/null +++ b/aws/internal/service/gamelift/waiter/status.go @@ -0,0 +1,33 @@ +package waiter + +import ( + "errors" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/gamelift" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func GameServerGroupState(conn *gamelift.GameLift, gameServerGroupID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + output, err := conn.DescribeGameServerGroup(&gamelift.DescribeGameServerGroupInput{ + GameServerGroupName: aws.String(gameServerGroupID), + }) + + if err != nil { + return nil, "", err + } + + if output == nil || output.GameServerGroup == nil { + return nil, "", nil + } + + status := aws.StringValue(output.GameServerGroup.Status) + + if status == gamelift.GameServerGroupStatusError { + return nil, status, errors.New(aws.StringValue(output.GameServerGroup.StatusReason)) + } + + return output.GameServerGroup, status, nil + } +} diff --git a/aws/internal/service/gamelift/waiter/waiter.go b/aws/internal/service/gamelift/waiter/waiter.go new file mode 100644 index 00000000000..f037231236e --- /dev/null +++ b/aws/internal/service/gamelift/waiter/waiter.go @@ -0,0 +1,51 @@ +package waiter + +import ( + "time" + + "github.com/aws/aws-sdk-go/service/gamelift" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func GameServerGroupActive(conn *gamelift.GameLift, gameServerGroupID string, timeout time.Duration) (*gamelift.GameServerGroup, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{ + gamelift.GameServerGroupStatusNew, + gamelift.GameServerGroupStatusActivating, + }, + Target: []string{ + gamelift.GameServerGroupStatusActive, + }, + Refresh: GameServerGroupState(conn, gameServerGroupID), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForState() + + if v, ok := outputRaw.(*gamelift.GameServerGroup); ok { + return v, err + } + + return nil, err +} + +func GameServerGroupDeleted(conn *gamelift.GameLift, gameServerGroupID string, timeout time.Duration) (*gamelift.GameServerGroup, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{ + gamelift.GameServerGroupStatusDeleteScheduled, + gamelift.GameServerGroupStatusDeleting, + gamelift.GameServerGroupStatusDeleted, + }, + Target: []string{}, + Refresh: GameServerGroupState(conn, gameServerGroupID), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForState() + + if v, ok := outputRaw.(*gamelift.GameServerGroup); ok { + return v, err + } + + return nil, err +} diff --git a/aws/provider.go b/aws/provider.go index 5de81c4636c..c71ded1d3d3 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -688,6 +688,7 @@ func Provider() *schema.Provider { "aws_gamelift_alias": resourceAwsGameliftAlias(), "aws_gamelift_build": resourceAwsGameliftBuild(), "aws_gamelift_fleet": resourceAwsGameliftFleet(), + "aws_gamelift_game_server_group": resourceAwsGameliftGameServerGroup(), "aws_gamelift_game_session_queue": resourceAwsGameliftGameSessionQueue(), "aws_glacier_vault": resourceAwsGlacierVault(), "aws_glacier_vault_lock": resourceAwsGlacierVaultLock(), diff --git a/aws/resource_aws_gamelift_game_server_group.go b/aws/resource_aws_gamelift_game_server_group.go new file mode 100644 index 00000000000..4406f91a8de --- /dev/null +++ b/aws/resource_aws_gamelift_game_server_group.go @@ -0,0 +1,531 @@ +package aws + +import ( + "fmt" + "log" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/autoscaling" + "github.com/aws/aws-sdk-go/service/gamelift" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/gamelift/waiter" +) + +func resourceAwsGameliftGameServerGroup() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsGameliftGameServerGroupCreate, + Read: resourceAwsGameliftGameServerGroupRead, + Update: resourceAwsGameliftGameServerGroupUpdate, + Delete: resourceAwsGameliftGameServerGroupDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "auto_scaling_group_arn": { + Type: schema.TypeString, + Computed: true, + }, + "auto_scaling_policy": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "estimated_instance_warmup": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validation.IntAtLeast(1), + }, + "target_tracking_configuration": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "target_value": { + Type: schema.TypeFloat, + Required: true, + ForceNew: true, + ValidateFunc: validation.FloatAtLeast(0), + }, + }, + }, + }, + }, + }, + }, + "balancing_strategy": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice(gamelift.BalancingStrategy_Values(), false), + }, + "game_server_group_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 128), + }, + "game_server_protection_policy": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice(gamelift.GameServerProtectionPolicy_Values(), false), + }, + "instance_definition": { + Type: schema.TypeSet, + Required: true, + MinItems: 2, + MaxItems: 20, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "instance_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(gamelift.GameServerGroupInstanceType_Values(), false), + }, + "weighted_capacity": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(1, 3), + }, + }, + }, + }, + "launch_template": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"launch_template.0.name"}, + ValidateFunc: validateLaunchTemplateId, + }, + "name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"launch_template.0.id"}, + ValidateFunc: validateLaunchTemplateName, + }, + "version": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 128), + }, + }, + }, + }, + "max_size": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + ValidateFunc: validation.IntAtLeast(1), + }, + "min_size": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + ValidateFunc: validation.IntAtLeast(0), + }, + "role_arn": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateArn, + }, + "tags": tagsSchema(), + "vpc_subnets": { + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + MaxItems: 20, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringLenBetween(15, 24), + }, + }, + }, + } +} + +func resourceAwsGameliftGameServerGroupCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).gameliftconn + + gameServerGroupName := d.Get("game_server_group_name").(string) + + input := gamelift.CreateGameServerGroupInput{ + GameServerGroupName: aws.String(gameServerGroupName), + InstanceDefinitions: expandGameliftInstanceDefinitions(d.Get("instance_definition").(*schema.Set).List()), + LaunchTemplate: expandGameliftLaunchTemplateSpecification(d.Get("launch_template").([]interface{})[0].(map[string]interface{})), + MaxSize: aws.Int64(int64(d.Get("max_size").(int))), + MinSize: aws.Int64(int64(d.Get("min_size").(int))), + RoleArn: aws.String(d.Get("role_arn").(string)), + Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().GameliftTags(), + } + + if v, ok := d.GetOk("auto_scaling_policy"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.AutoScalingPolicy = expandGameliftGameServerGroupAutoScalingPolicy(v.([]interface{})[0].(map[string]interface{})) + } + + if v, ok := d.GetOk("balancing_strategy"); ok { + input.BalancingStrategy = aws.String(v.(string)) + } + + if v, ok := d.GetOk("game_server_protection_policy"); ok { + input.GameServerProtectionPolicy = aws.String(v.(string)) + } + + if v, ok := d.GetOk("vpc_subnets"); ok && v.(*schema.Set).Len() > 0 { + input.VpcSubnets = expandStringSet(v.(*schema.Set)) + } + + _, err := conn.CreateGameServerGroup(&input) + + if err != nil { + return fmt.Errorf("error creating GameLift Game Server Group: %w", err) + } + + d.SetId(gameServerGroupName) + + if _, err := waiter.GameServerGroupActive(conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { + return fmt.Errorf("error waiting for Gamelift Game Server Group (%s) to be active: %w", d.Id(), err) + } + + return resourceAwsGameliftGameServerGroupRead(d, meta) +} + +func resourceAwsGameliftGameServerGroupRead(d *schema.ResourceData, meta interface{}) error { + autoscalingconn := meta.(*AWSClient).autoscalingconn + gameliftconn := meta.(*AWSClient).gameliftconn + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + + gameServerGroupName := d.Id() + + describeGameServerGroupOutput, err := gameliftconn.DescribeGameServerGroup(&gamelift.DescribeGameServerGroupInput{ + GameServerGroupName: aws.String(gameServerGroupName), + }) + + if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, gamelift.ErrCodeNotFoundException) { + log.Printf("[WARN] Gamelift Game Server Group (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return fmt.Errorf("error reading Gamelift Game Server Group (%s): %w", d.Id(), err) + } + + gameServerGroup := describeGameServerGroupOutput.GameServerGroup + + // To view properties of automatically created Auto Scaling group users should access it directly: + // https://docs.aws.amazon.com/gamelift/latest/apireference/API_DescribeGameServerGroup.html + autoScalingGroupName := strings.Split(aws.StringValue(gameServerGroup.AutoScalingGroupArn), "/")[1] + autoScalingGroup, err := getAwsAutoscalingGroup(autoScalingGroupName, autoscalingconn) + + if err != nil { + return err + } + + if autoScalingGroup == nil { + return fmt.Errorf("error describing Auto Scaling Group (%s): not found", autoScalingGroupName) + } + + describePoliciesOutput, err := autoscalingconn.DescribePolicies(&autoscaling.DescribePoliciesInput{ + AutoScalingGroupName: aws.String(autoScalingGroupName), + PolicyNames: []*string{aws.String(gameServerGroupName)}, + }) + + if err != nil { + return fmt.Errorf("error describing Auto Scaling Group Policies (%s): %s", autoScalingGroupName, err) + } + + arn := aws.StringValue(gameServerGroup.GameServerGroupArn) + d.Set("arn", arn) + d.Set("auto_scaling_group_arn", gameServerGroup.AutoScalingGroupArn) + d.Set("balancing_strategy", gameServerGroup.BalancingStrategy) + d.Set("game_server_group_name", gameServerGroupName) + d.Set("game_server_protection_policy", gameServerGroup.GameServerProtectionPolicy) + d.Set("max_size", autoScalingGroup.MaxSize) + d.Set("min_size", autoScalingGroup.MinSize) + d.Set("role_arn", gameServerGroup.RoleArn) + + // d.Set("vpc_subnets", ...) is absent because Gamelift doesn't return its value in API + // and dynamically changes autoScalingGroup.VPCZoneIdentifier using its proprietary FleetIQ Spot Viability algorithm. + + if len(describePoliciesOutput.ScalingPolicies) == 1 { + if err := d.Set("auto_scaling_policy", []interface{}{flattenGameliftGameServerGroupAutoScalingPolicy(describePoliciesOutput.ScalingPolicies[0])}); err != nil { + return fmt.Errorf("error setting auto_scaling_policy: %w", err) + } + } else { + d.Set("auto_scaling_policy", nil) + } + + if err := d.Set("instance_definition", flattenGameliftInstanceDefinitions(gameServerGroup.InstanceDefinitions)); err != nil { + return fmt.Errorf("error setting instance_definition: %s", err) + } + + if err := d.Set("launch_template", flattenLaunchTemplateSpecification(autoScalingGroup.MixedInstancesPolicy.LaunchTemplate.LaunchTemplateSpecification)); err != nil { + return fmt.Errorf("error setting launch_template: %s", err) + } + + tags, err := keyvaluetags.GameliftListTags(gameliftconn, arn) + + if err != nil { + return fmt.Errorf("error listing tags for Game Lift Game Server Group (%s): %s", arn, err) + } + + if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %s", err) + } + + return nil +} + +func resourceAwsGameliftGameServerGroupUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).gameliftconn + + gameServerGroupName := d.Id() + + if d.HasChanges("balancing_strategy", "game_server_protection_policy", "instance_definition", "role_arn") { + input := gamelift.UpdateGameServerGroupInput{ + GameServerGroupName: aws.String(gameServerGroupName), + InstanceDefinitions: expandGameliftInstanceDefinitions(d.Get("instance_definition").(*schema.Set).List()), + RoleArn: aws.String(d.Get("role_arn").(string)), + } + + if v, ok := d.GetOk("balancing_strategy"); ok { + input.BalancingStrategy = aws.String(v.(string)) + } + + if v, ok := d.GetOk("game_server_protection_policy"); ok { + input.GameServerProtectionPolicy = aws.String(v.(string)) + } + + _, err := conn.UpdateGameServerGroup(&input) + + if err != nil { + return fmt.Errorf("error updating GameLift Game Server Group (%s): %w", d.Id(), err) + } + } + + arn := d.Get("arn").(string) + + if d.HasChange("tags") { + o, n := d.GetChange("tags") + + if err := keyvaluetags.GameliftUpdateTags(conn, arn, o, n); err != nil { + return fmt.Errorf("error updating Game Lift Fleet (%s) tags: %s", arn, err) + } + } + + return resourceAwsGameliftGameServerGroupRead(d, meta) +} + +func resourceAwsGameliftGameServerGroupDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).gameliftconn + + gameServerGroupName := d.Id() + + _, err := conn.DeleteGameServerGroup(&gamelift.DeleteGameServerGroupInput{ + GameServerGroupName: aws.String(gameServerGroupName), + }) + + if tfawserr.ErrCodeEquals(err, gamelift.ErrCodeNotFoundException) { + return nil + } + + if err != nil { + return fmt.Errorf("error deleting Gamelift Game Server Group (%s): %w", d.Id(), err) + } + + _, err = waiter.GameServerGroupDeleted(conn, d.Id(), d.Timeout(schema.TimeoutDelete)) + + if tfawserr.ErrCodeEquals(err, gamelift.ErrCodeNotFoundException) { + return nil + } + + if err != nil { + return fmt.Errorf("error waiting for Gamelift Game Server Group (%s) deletion: %w", d.Id(), err) + } + + return nil +} + +func expandGameliftGameServerGroupAutoScalingPolicy(tfMap map[string]interface{}) *gamelift.GameServerGroupAutoScalingPolicy { + if tfMap == nil { + return nil + } + + apiObject := &gamelift.GameServerGroupAutoScalingPolicy{ + TargetTrackingConfiguration: expandGameliftTargetTrackingConfiguration(tfMap["target_tracking_configuration"].([]interface{})[0].(map[string]interface{})), + } + + if v, ok := tfMap["estimated_instance_warmup"].(int); ok && v != 0 { + apiObject.EstimatedInstanceWarmup = aws.Int64(int64(v)) + } + + return apiObject +} + +func expandGameliftInstanceDefinition(tfMap map[string]interface{}) *gamelift.InstanceDefinition { + if tfMap == nil { + return nil + } + + apiObject := &gamelift.InstanceDefinition{ + InstanceType: aws.String(tfMap["instance_type"].(string)), + } + + if v, ok := tfMap["weighted_capacity"].(string); ok && v != "" { + apiObject.WeightedCapacity = aws.String(v) + } + + return apiObject +} + +func expandGameliftInstanceDefinitions(tfList []interface{}) []*gamelift.InstanceDefinition { + if len(tfList) == 0 { + return nil + } + + var apiObjects []*gamelift.InstanceDefinition + + for _, tfMapRaw := range tfList { + tfMap, ok := tfMapRaw.(map[string]interface{}) + + if !ok { + continue + } + + apiObject := expandGameliftInstanceDefinition(tfMap) + + if apiObject == nil { + continue + } + + apiObjects = append(apiObjects, apiObject) + } + + return apiObjects +} + +func expandGameliftLaunchTemplateSpecification(tfMap map[string]interface{}) *gamelift.LaunchTemplateSpecification { + if tfMap == nil { + return nil + } + + apiObject := &gamelift.LaunchTemplateSpecification{} + + if v, ok := tfMap["id"].(string); ok && v != "" { + apiObject.LaunchTemplateId = aws.String(v) + } + + if v, ok := tfMap["name"].(string); ok && v != "" { + apiObject.LaunchTemplateName = aws.String(v) + } + + if v, ok := tfMap["version"].(string); ok && v != "" { + apiObject.Version = aws.String(v) + } + + return apiObject +} + +func expandGameliftTargetTrackingConfiguration(tfMap map[string]interface{}) *gamelift.TargetTrackingConfiguration { + if tfMap == nil { + return nil + } + + apiObject := &gamelift.TargetTrackingConfiguration{ + TargetValue: aws.Float64(tfMap["target_value"].(float64)), + } + + return apiObject +} + +func flattenGameliftGameServerGroupAutoScalingPolicy(apiObject *autoscaling.ScalingPolicy) map[string]interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{ + "target_tracking_configuration": []interface{}{flattenGameliftTargetTrackingConfiguration(apiObject.TargetTrackingConfiguration)}, + } + + if v := apiObject.EstimatedInstanceWarmup; v != nil { + tfMap["estimated_instance_warmup"] = aws.Int64Value(v) + } + + return tfMap +} + +func flattenGameliftInstanceDefinition(apiObject *gamelift.InstanceDefinition) map[string]interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{ + "instance_type": aws.StringValue(apiObject.InstanceType), + } + + if v := apiObject.WeightedCapacity; v != nil { + tfMap["weighted_capacity"] = aws.StringValue(v) + } + + return tfMap +} + +func flattenGameliftInstanceDefinitions(apiObjects []*gamelift.InstanceDefinition) []interface{} { + if len(apiObjects) == 0 { + return nil + } + + var tfList []interface{} + + for _, apiObject := range apiObjects { + if apiObject == nil { + continue + } + + tfList = append(tfList, flattenGameliftInstanceDefinition(apiObject)) + } + + return tfList +} + +func flattenGameliftTargetTrackingConfiguration(apiObject *autoscaling.TargetTrackingConfiguration) map[string]interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{ + "target_value": aws.Float64Value(apiObject.TargetValue), + } + + return tfMap +} diff --git a/aws/resource_aws_gamelift_game_server_group_test.go b/aws/resource_aws_gamelift_game_server_group_test.go new file mode 100644 index 00000000000..6171796f7c4 --- /dev/null +++ b/aws/resource_aws_gamelift_game_server_group_test.go @@ -0,0 +1,1238 @@ +package aws + +import ( + "fmt" + "log" + "regexp" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/gamelift" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/go-multierror" + "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" +) + +func init() { + resource.AddTestSweepers("aws_gamelift_game_server_group", &resource.Sweeper{ + Name: "aws_gamelift_game_server_group", + F: testSweepGameliftGameServerGroups, + }) +} + +func testSweepGameliftGameServerGroups(region string) error { + client, err := sharedClientForRegion(region) + + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + + conn := client.(*AWSClient).gameliftconn + input := &gamelift.ListGameServerGroupsInput{} + var sweeperErrs *multierror.Error + + err = conn.ListGameServerGroupsPages(input, func(page *gamelift.ListGameServerGroupsOutput, isLast bool) bool { + if page == nil { + return !isLast + } + + for _, gameServerGroup := range page.GameServerGroups { + id := aws.StringValue(gameServerGroup.GameServerGroupName) + + input := &gamelift.DeleteGameServerGroupInput{ + GameServerGroupName: gameServerGroup.GameServerGroupName, + } + + log.Printf("[INFO] Deleting Gamelift Game Server Group: %s", id) + _, err := conn.DeleteGameServerGroup(input) + + if err != nil { + sweeperErr := fmt.Errorf("error deleting Gamelift Game Server Group (%s): %w", id, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + + return !isLast + }) + + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping Gamelift Game Server Group sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() + } + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving Gamelift Game Server Groups: %w", err)) + } + + return sweeperErrs.ErrorOrNil() +} + +func TestAccGameliftGameServerGroup_basic(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAWSGamelift(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "gamelift", fmt.Sprintf(`gameservergroup/%s`, rName)), + testAccMatchResourceAttrRegionalARN(resourceName, "auto_scaling_group_arn", "autoscaling", regexp.MustCompile(`autoScalingGroup:.+`)), + resource.TestCheckResourceAttr(resourceName, "auto_scaling_policy.#", "0"), + resource.TestCheckResourceAttr(resourceName, "balancing_strategy", gamelift.BalancingStrategySpotPreferred), + resource.TestCheckResourceAttr(resourceName, "game_server_protection_policy", gamelift.GameServerProtectionPolicyNoProtection), + resource.TestCheckResourceAttr(resourceName, "launch_template.0.version", ""), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_AutoScalingPolicy(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAWSGamelift(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigAutoScalingPolicy(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auto_scaling_policy.0.estimated_instance_warmup", "60"), + resource.TestCheckResourceAttr(resourceName, "auto_scaling_policy.0.target_tracking_configuration.0.target_value", "77.7"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_AutoScalingPolicy_EstimatedInstanceWarmup(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAWSGamelift(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigAutoScalingPolicyEstimatedInstanceWarmup(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auto_scaling_policy.0.estimated_instance_warmup", "66"), + resource.TestCheckResourceAttr(resourceName, "auto_scaling_policy.0.target_tracking_configuration.0.target_value", "77.7"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_BalancingStrategy(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAWSGamelift(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigBalancingStrategy(rName, gamelift.BalancingStrategySpotOnly), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "balancing_strategy", gamelift.BalancingStrategySpotOnly), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_GameServerGroupName(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAWSGamelift(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigGameServerGroupName(rName, rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "game_server_group_name", rName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGameliftGameServerGroupConfigGameServerGroupName(rName, rName+"-new"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "game_server_group_name", rName+"-new"), + ), + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_InstanceDefinition(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAWSGamelift(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigInstanceDefinition(rName, 2), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "instance_definition.#", "2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGameliftGameServerGroupConfigInstanceDefinition(rName, 3), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "instance_definition.#", "3"), + ), + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_InstanceDefinition_WeightedCapacity(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAWSGamelift(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigInstanceDefinitionWeightedCapacity(rName, "1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "instance_definition.#", "2"), + resource.TestCheckResourceAttr(resourceName, "instance_definition.0.weighted_capacity", "1"), + resource.TestCheckResourceAttr(resourceName, "instance_definition.1.weighted_capacity", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGameliftGameServerGroupConfigInstanceDefinitionWeightedCapacity(rName, "2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "instance_definition.#", "2"), + resource.TestCheckResourceAttr(resourceName, "instance_definition.0.weighted_capacity", "2"), + resource.TestCheckResourceAttr(resourceName, "instance_definition.1.weighted_capacity", "2"), + ), + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_LaunchTemplate_Id(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAWSGamelift(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigLaunchTemplateId(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "launch_template.0.id", "aws_launch_template.test", "id"), + resource.TestCheckResourceAttr(resourceName, "launch_template.0.name", rName), + resource.TestCheckResourceAttr(resourceName, "launch_template.0.version", ""), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_LaunchTemplate_Name(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAWSGamelift(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigLaunchTemplateName(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "launch_template.0.id", "aws_launch_template.test", "id"), + resource.TestCheckResourceAttr(resourceName, "launch_template.0.name", rName), + resource.TestCheckResourceAttr(resourceName, "launch_template.0.version", ""), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_LaunchTemplate_Version(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAWSGamelift(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigLaunchTemplateVersion(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "launch_template.0.id", "aws_launch_template.test", "id"), + resource.TestCheckResourceAttr(resourceName, "launch_template.0.name", rName), + resource.TestCheckResourceAttr(resourceName, "launch_template.0.version", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_GameServerProtectionPolicy(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAWSGamelift(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigGameServerProtectionPolicy(rName, gamelift.GameServerProtectionPolicyFullProtection), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "game_server_protection_policy", gamelift.GameServerProtectionPolicyFullProtection), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_MaxSize(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAWSGamelift(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigMaxSize(rName, "1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "max_size", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGameliftGameServerGroupConfigMaxSize(rName, "2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "max_size", "2"), + ), + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_MinSize(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAWSGamelift(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigMinSize(rName, "1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "min_size", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGameliftGameServerGroupConfigMinSize(rName, "2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "min_size", "2"), + ), + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_RoleArn(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAWSGamelift(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigRoleArn(rName, "test1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + testAccCheckResourceAttrGlobalARN(resourceName, "role_arn", "iam", fmt.Sprintf(`role/%s-test1`, rName)), + resource.TestCheckResourceAttrPair(resourceName, "role_arn", "aws_iam_role.test1", "arn"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGameliftGameServerGroupConfigRoleArn(rName, "test2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + testAccCheckResourceAttrGlobalARN(resourceName, "role_arn", "iam", fmt.Sprintf(`role/%s-test2`, rName)), + resource.TestCheckResourceAttrPair(resourceName, "role_arn", "aws_iam_role.test2", "arn"), + ), + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_Tags(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAWSGamelift(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigTags(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGameliftGameServerGroupConfigTags(rName, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_VpcSubnets(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAWSGamelift(t) + }, + Providers: testAccProviders, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigVpcSubnets(rName, 1), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"vpc_subnets"}, + }, + { + Config: testAccGameliftGameServerGroupConfigVpcSubnets(rName, 2), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + ), + }, + }, + }) +} + +func testAccCheckGameliftGameServerGroupDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).gameliftconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_gamelift_game_server_group" { + continue + } + + input := gamelift.DescribeGameServerGroupInput{ + GameServerGroupName: aws.String(rs.Primary.ID), + } + + output, err := conn.DescribeGameServerGroup(&input) + + if tfawserr.ErrCodeEquals(err, gamelift.ErrCodeNotFoundException) { + continue + } + + if err != nil { + return err + } + + if output != nil { + return fmt.Errorf("Gamelift Game Server Group (%s) still exists", rs.Primary.ID) + } + } + + return nil +} + +func testAccCheckGameliftGameServerGroupExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + + if !ok { + return fmt.Errorf("resource %s not found", resourceName) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("resource %s has not set its id", resourceName) + } + + conn := testAccProvider.Meta().(*AWSClient).gameliftconn + + input := gamelift.DescribeGameServerGroupInput{ + GameServerGroupName: aws.String(rs.Primary.ID), + } + + output, err := conn.DescribeGameServerGroup(&input) + + if err != nil { + return fmt.Errorf("error reading Gamelift Game Server Group (%s): %w", rs.Primary.ID, err) + } + + if output == nil { + return fmt.Errorf("Gamelift Game Server Group (%s) not found", rs.Primary.ID) + } + + return nil + } +} + +func testAccGameliftGameServerGroupIamConfig(rName string, name string) string { + return fmt.Sprintf(` +data "aws_partition" "current" {} + +resource "aws_iam_role" %[2]q { + assume_role_policy = <<-EOF + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": [ + "autoscaling.amazonaws.com", + "gamelift.amazonaws.com" + ] + }, + "Action": "sts:AssumeRole" + } + ] + } + EOF + + name = "%[1]s-%[2]s" +} + +resource "aws_iam_role_policy_attachment" %[2]q { + policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/GameLiftGameServerGroupPolicy" + role = aws_iam_role.%[2]s.name +} +`, rName, name) +} + +func testAccGameliftGameServerGroupLaunchTemplateConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_launch_template" "test" { + image_id = data.aws_ami.amzn-ami-minimal-hvm-ebs.id + name = %[1]q +} +`, rName) +} + +func testAccGameliftGameServerGroupInstanceTypeOfferingsConfig() string { + return ` +data "aws_ec2_instance_type_offerings" "available" { + filter { + name = "instance-type" + values = ["c5a.large", "c5a.2xlarge", "c5.large", "c5.2xlarge", "m4.large", "m4.2xlarge", "m5a.large", "m5a.2xlarge", "m5.large", "m5.2xlarge"] + } +} +` +} + +func testAccGameliftGameServerGroupConfig(rName string) string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + + content { + instance_type = instance_definition.key + } + } + + launch_template { + id = aws_launch_template.test.id + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName)) +} + +func testAccGameliftGameServerGroupConfigAutoScalingPolicy(rName string) string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + auto_scaling_policy { + target_tracking_configuration { + target_value = 77.7 + } + } + + game_server_group_name = %[1]q + + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + + content { + instance_type = instance_definition.key + } + } + + launch_template { + id = aws_launch_template.test.id + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName)) +} + +func testAccGameliftGameServerGroupConfigAutoScalingPolicyEstimatedInstanceWarmup(rName string) string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + auto_scaling_policy { + estimated_instance_warmup = 66 + + target_tracking_configuration { + target_value = 77.7 + } + } + + game_server_group_name = %[1]q + + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + + content { + instance_type = instance_definition.key + } + } + + launch_template { + id = aws_launch_template.test.id + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName)) +} + +func testAccGameliftGameServerGroupConfigBalancingStrategy(rName string, balancingStrategy string) string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + balancing_strategy = %[2]q + game_server_group_name = %[1]q + + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + + content { + instance_type = instance_definition.key + } + } + + launch_template { + id = aws_launch_template.test.id + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName, balancingStrategy)) +} + +func testAccGameliftGameServerGroupConfigGameServerGroupName(rName string, gameServerGroupName string) string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + + content { + instance_type = instance_definition.key + } + } + + launch_template { + id = aws_launch_template.test.id + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + + depends_on = [aws_iam_role_policy_attachment.test] +} +`, gameServerGroupName)) +} + +func testAccGameliftGameServerGroupConfigInstanceDefinition(rName string, count int) string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + + dynamic "instance_definition" { + for_each = slice(tolist(data.aws_ec2_instance_type_offerings.available.instance_types), 0, %[2]d) + + content { + instance_type = instance_definition.value + } + } + + launch_template { + id = aws_launch_template.test.id + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName, count)) +} + +func testAccGameliftGameServerGroupConfigInstanceDefinitionWeightedCapacity(rName string, weightedCapacity string) string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + + dynamic "instance_definition" { + for_each = slice(tolist(data.aws_ec2_instance_type_offerings.available.instance_types), 0, 2) + + content { + instance_type = instance_definition.value + weighted_capacity = %[2]q + } + } + + launch_template { + id = aws_launch_template.test.id + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName, weightedCapacity)) +} +func testAccGameliftGameServerGroupConfigLaunchTemplateId(rName string) string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + + content { + instance_type = instance_definition.key + } + } + + launch_template { + id = aws_launch_template.test.id + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName)) +} + +func testAccGameliftGameServerGroupConfigLaunchTemplateName(rName string) string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + + content { + instance_type = instance_definition.key + } + } + + launch_template { + name = aws_launch_template.test.name + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName)) +} + +func testAccGameliftGameServerGroupConfigLaunchTemplateVersion(rName string) string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + + content { + instance_type = instance_definition.key + } + } + + launch_template { + id = aws_launch_template.test.id + version = 1 + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName)) +} + +func testAccGameliftGameServerGroupConfigMaxSize(rName string, maxSize string) string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + + content { + instance_type = instance_definition.key + } + } + + launch_template { + id = aws_launch_template.test.id + } + + max_size = %[2]s + min_size = 1 + role_arn = aws_iam_role.test.arn + + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName, maxSize)) +} + +func testAccGameliftGameServerGroupConfigMinSize(rName string, minSize string) string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + + content { + instance_type = instance_definition.key + } + } + + launch_template { + id = aws_launch_template.test.id + } + + max_size = 2 + min_size = %[2]s + role_arn = aws_iam_role.test.arn + + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName, minSize)) +} + +func testAccGameliftGameServerGroupConfigTags(rName string, key string, value string) string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + + content { + instance_type = instance_definition.key + } + } + + launch_template { + id = aws_launch_template.test.id + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + + tags = { + %[2]s = %[3]q + } + + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName, key, value)) +} + +func testAccGameliftGameServerGroupConfigGameServerProtectionPolicy(rName string, gameServerProtectionPolicy string) string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + game_server_protection_policy = %[2]q + + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + + content { + instance_type = instance_definition.key + } + } + + launch_template { + id = aws_launch_template.test.id + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName, gameServerProtectionPolicy)) +} + +func testAccGameliftGameServerGroupConfigRoleArn(rName string, roleArn string) string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccGameliftGameServerGroupIamConfig(rName, roleArn), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + + content { + instance_type = instance_definition.key + } + } + + launch_template { + id = aws_launch_template.test.id + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.%[2]s.arn + + depends_on = [aws_iam_role_policy_attachment.%[2]s] +} +`, rName, roleArn)) +} + +func testAccGameliftGameServerGroupConfigVpcSubnets(rName string, count int) string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +data "aws_vpc" "test" { + default = true +} + +data "aws_subnet_ids" "test" { + vpc_id = data.aws_vpc.test.id +} + +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + + content { + instance_type = instance_definition.key + } + } + + launch_template { + id = aws_launch_template.test.id + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + vpc_subnets = slice(tolist(data.aws_subnet_ids.test.ids), 0, %[2]d) + + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName, count)) +} diff --git a/website/docs/r/gamelift_game_server_group.html.markdown b/website/docs/r/gamelift_game_server_group.html.markdown new file mode 100644 index 00000000000..b72a9d42ac8 --- /dev/null +++ b/website/docs/r/gamelift_game_server_group.html.markdown @@ -0,0 +1,206 @@ +--- +subcategory: "Gamelift" +layout: "aws" +page_title: "AWS: aws_gamelift_game_server_group" +description: |- +Provides a Gamelift Game Server Group resource. +--- + +# Resource: aws_gamelift_game_server_group + +Provides an Gamelift Game Server Group resource. + +## Example Usage + +Basic usage: + +```hcl +resource "aws_gamelift_game_server_group" "example" { + game_server_group_name = "example" + + instance_definition { + instance_type = "c5.large" + } + + instance_definition { + instance_type = "c5a.large" + } + + launch_template { + id = aws_launch_template.example.id + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.example.arn + + depends_on = [ + aws_iam_role_policy_attachment.example + ] +} +``` + +Full usage: + +```hcl +resource "aws_gamelift_game_server_group" "example" { + auto_scaling_policy { + estimated_instance_warmup = 60 + + target_tracking_configuration { + target_value = 75 + } + } + + balancing_strategy = "SPOT_ONLY" + game_server_group_name = "example" + game_server_protection_policy = "FULL_PROTECTION" + + instance_definition { + instance_type = "c5.large" + weighted_capacity = "1" + } + + instance_definition { + instance_type = "c5.2xlarge" + weighted_capacity = "2" + } + + launch_template { + id = aws_launch_template.example.id + version = "1" + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.example.arn + + tags = { + Name = "example" + } + + vpc_subnets = [ + "subnet-12345678", + "subnet-23456789" + ] + + depends_on = [ + aws_iam_role_policy_attachment.example + ] +} +``` + +### Example IAM Role for Gamelift Game Server Group +```hcl +data "aws_partition" "current" {} + +resource "aws_iam_role" "example" { + assume_role_policy = <<-EOF + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": [ + "autoscaling.amazonaws.com", + "gamelift.amazonaws.com" + ] + }, + "Action": "sts:AssumeRole" + } + ] + } + EOF + + name = "gamelift-game-server-group-example" +} + +resource "aws_iam_role_policy_attachment" "example" { + policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/GameLiftGameServerGroupPolicy" + role = aws_iam_role.example.name +} +``` + +## Argument Reference + +The following arguments are supported: + +* `balancing_strategy` - (Optional) Indicates how GameLift FleetIQ balances the use of Spot Instances and On-Demand Instances. + Valid values: `SPOT_ONLY`, `SPOT_PREFERRED`, `ON_DEMAND_ONLY`. Defaults to `SPOT_PREFERRED`. +* `game_server_group_name` - (Required) Name of the game server group. + This value is used to generate unique ARN identifiers for the EC2 Auto Scaling group and the GameLift FleetIQ game server group. +* `game_server_protection_policy` - (Optional) Indicates whether instances in the game server group are protected from early termination. + Unprotected instances that have active game servers running might be terminated during a scale-down event, + causing players to be dropped from the game. + Protected instances cannot be terminated while there are active game servers running except in the event + of a forced game server group deletion. + Valid values: `NO_PROTECTION`, `FULL_PROTECTION`. Defaults to `NO_PROTECTION`. +* `max_size` - (Required) The maximum number of instances allowed in the EC2 Auto Scaling group. + During automatic scaling events, GameLift FleetIQ and EC2 do not scale up the group above this maximum. +* `min_size` - (Required) The minimum number of instances allowed in the EC2 Auto Scaling group. + During automatic scaling events, GameLift FleetIQ and EC2 do not scale down the group below this minimum. +* `role_arn` - (Required) ARN for an IAM role that allows Amazon GameLift to access your EC2 Auto Scaling groups. +* `tags` - (Optional) Key-value map of resource tags +* `vpc_subnets` - (Optional) A list of VPC subnets to use with instances in the game server group. + By default, all GameLift FleetIQ-supported Availability Zones are used. + +### `auto_scaling_policy` +Configuration settings to define a scaling policy for the Auto Scaling group that is optimized for game hosting. +The scaling policy uses the metric `PercentUtilizedGameServers` to maintain a buffer of idle game servers that +can immediately accommodate new games and players. + +* `estimated_instance_warmup` - (Optional) Length of time, in seconds, it takes for a new instance to start + new game server processes and register with GameLift FleetIQ. + Specifying a warm-up time can be useful, particularly with game servers that take a long time to start up, + because it avoids prematurely starting new instances. Defaults to `60`. + +#### `target_tracking_configuration` +Settings for a target-based scaling policy applied to Auto Scaling group. +These settings are used to create a target-based policy that tracks the GameLift FleetIQ metric `PercentUtilizedGameServers` +and specifies a target value for the metric. + +* `target_value` - (Required) Desired value to use with a game server group target-based scaling policy. + +### `instance_definition` +The EC2 instance types and sizes to use in the Auto Scaling group. +The instance definitions must specify at least two different instance types that are supported by GameLift FleetIQ. + +* `instance_type` - (Required) An EC2 instance type. +* `weighted_capacity` - (Optional) Instance weighting that indicates how much this instance type contributes + to the total capacity of a game server group. + Instance weights are used by GameLift FleetIQ to calculate the instance type's cost per unit hour and better identify + the most cost-effective options. + +### `launch_template` +The EC2 launch template that contains configuration settings and game server code to be deployed to all instances in the game server group. +You can specify the template using either the template name or ID. + +* `id` - (Optional) A unique identifier for an existing EC2 launch template. +* `name` - (Optional) A readable identifier for an existing EC2 launch template. +* `version` - (Optional) The version of the EC2 launch template to use. If none is set, the default is the first version created. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The name of the Gamelift Game Server Group. +* `arn` - The ARN of the Gamelift Game Server Group. +* `auto_scaling_group_arn` - The ARN of the created EC2 Auto Scaling group. + + +## Timeouts + +`aws_gamelift_game_server_group` provides the following +[Timeouts](https://www.terraform.io/docs/configuration/blocks/resources/syntax.html#operation-timeouts) configuration options: + +* `create` - (Default `10 minutes`) How long to wait for the Gamelift Game Server Group to be created. +* `delete` - (Default `30 minutes`) How long to wait for the Gamelift Game Server Group to be deleted. + +## Import + +Gamelift Game Server Group can be imported using the `name`, e.g. + +``` +$ terraform import aws_gamelift_game_server_group.example example +``` From 4a56c1e38cc2258616e4c67adba394fbbc5729e4 Mon Sep 17 00:00:00 2001 From: Mykola Ulianytskyi Date: Tue, 9 Mar 2021 19:31:48 +0200 Subject: [PATCH 023/229] r/aws_gamelift_game_server_group: Add changelog --- .changelog/18003.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/18003.txt diff --git a/.changelog/18003.txt b/.changelog/18003.txt new file mode 100644 index 00000000000..7827744e5db --- /dev/null +++ b/.changelog/18003.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_gamelift_game_server_group +``` From 0168e5fa49dd5083d1b509b8b6166b08b0e5f3ba Mon Sep 17 00:00:00 2001 From: Mykola Ulianytskyi Date: Tue, 9 Mar 2021 21:28:15 +0200 Subject: [PATCH 024/229] r/aws_gamelift_game_server_group: Fix formatting --- ...rce_aws_gamelift_game_server_group_test.go | 26 ++++----- .../gamelift_game_server_group.html.markdown | 54 ++++++++++--------- 2 files changed, 42 insertions(+), 38 deletions(-) diff --git a/aws/resource_aws_gamelift_game_server_group_test.go b/aws/resource_aws_gamelift_game_server_group_test.go index 6171796f7c4..59c614a6805 100644 --- a/aws/resource_aws_gamelift_game_server_group_test.go +++ b/aws/resource_aws_gamelift_game_server_group_test.go @@ -660,7 +660,7 @@ func testAccCheckGameliftGameServerGroupExists(resourceName string) resource.Tes func testAccGameliftGameServerGroupIamConfig(rName string, name string) string { return fmt.Sprintf(` -data "aws_partition" "current" {} +data "aws_partition" %[2]q {} resource "aws_iam_role" %[2]q { assume_role_policy = <<-EOF @@ -685,7 +685,7 @@ resource "aws_iam_role" %[2]q { } resource "aws_iam_role_policy_attachment" %[2]q { - policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/GameLiftGameServerGroupPolicy" + policy_arn = "arn:${data.aws_partition.%[2]s.partition}:iam::aws:policy/GameLiftGameServerGroupPolicy" role = aws_iam_role.%[2]s.name } `, rName, name) @@ -695,7 +695,7 @@ func testAccGameliftGameServerGroupLaunchTemplateConfig(rName string) string { return fmt.Sprintf(` resource "aws_launch_template" "test" { image_id = data.aws_ami.amzn-ami-minimal-hvm-ebs.id - name = %[1]q + name = %[1]q } `, rName) } @@ -704,7 +704,7 @@ func testAccGameliftGameServerGroupInstanceTypeOfferingsConfig() string { return ` data "aws_ec2_instance_type_offerings" "available" { filter { - name = "instance-type" + name = "instance-type" values = ["c5a.large", "c5a.2xlarge", "c5.large", "c5.2xlarge", "m4.large", "m4.2xlarge", "m5a.large", "m5a.2xlarge", "m5.large", "m5.2xlarge"] } } @@ -826,7 +826,7 @@ func testAccGameliftGameServerGroupConfigBalancingStrategy(rName string, balanci testAccGameliftGameServerGroupLaunchTemplateConfig(rName), fmt.Sprintf(` resource "aws_gamelift_game_server_group" "test" { - balancing_strategy = %[2]q + balancing_strategy = %[2]q game_server_group_name = %[1]q dynamic "instance_definition" { @@ -892,7 +892,7 @@ resource "aws_gamelift_game_server_group" "test" { game_server_group_name = %[1]q dynamic "instance_definition" { - for_each = slice(tolist(data.aws_ec2_instance_type_offerings.available.instance_types), 0, %[2]d) + for_each = slice(tolist(data.aws_ec2_instance_type_offerings.available.instance_types), 0, %[2]d) content { instance_type = instance_definition.value @@ -923,7 +923,7 @@ resource "aws_gamelift_game_server_group" "test" { game_server_group_name = %[1]q dynamic "instance_definition" { - for_each = slice(tolist(data.aws_ec2_instance_type_offerings.available.instance_types), 0, 2) + for_each = slice(tolist(data.aws_ec2_instance_type_offerings.available.instance_types), 0, 2) content { instance_type = instance_definition.value @@ -1093,7 +1093,7 @@ resource "aws_gamelift_game_server_group" "test" { max_size = 2 min_size = %[2]s role_arn = aws_iam_role.test.arn - + depends_on = [aws_iam_role_policy_attachment.test] } `, rName, minSize)) @@ -1180,7 +1180,7 @@ resource "aws_gamelift_game_server_group" "test" { for_each = data.aws_ec2_instance_type_offerings.available.instance_types content { - instance_type = instance_definition.key + instance_type = instance_definition.key } } @@ -1219,7 +1219,7 @@ resource "aws_gamelift_game_server_group" "test" { for_each = data.aws_ec2_instance_type_offerings.available.instance_types content { - instance_type = instance_definition.key + instance_type = instance_definition.key } } @@ -1227,9 +1227,9 @@ resource "aws_gamelift_game_server_group" "test" { id = aws_launch_template.test.id } - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.test.arn + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn vpc_subnets = slice(tolist(data.aws_subnet_ids.test.ids), 0, %[2]d) depends_on = [aws_iam_role_policy_attachment.test] diff --git a/website/docs/r/gamelift_game_server_group.html.markdown b/website/docs/r/gamelift_game_server_group.html.markdown index b72a9d42ac8..56d4ef165f6 100644 --- a/website/docs/r/gamelift_game_server_group.html.markdown +++ b/website/docs/r/gamelift_game_server_group.html.markdown @@ -3,7 +3,7 @@ subcategory: "Gamelift" layout: "aws" page_title: "AWS: aws_gamelift_game_server_group" description: |- -Provides a Gamelift Game Server Group resource. + Provides a Gamelift Game Server Group resource. --- # Resource: aws_gamelift_game_server_group @@ -52,22 +52,22 @@ resource "aws_gamelift_game_server_group" "example" { } } - balancing_strategy = "SPOT_ONLY" - game_server_group_name = "example" + balancing_strategy = "SPOT_ONLY" + game_server_group_name = "example" game_server_protection_policy = "FULL_PROTECTION" instance_definition { - instance_type = "c5.large" + instance_type = "c5.large" weighted_capacity = "1" } instance_definition { - instance_type = "c5.2xlarge" + instance_type = "c5.2xlarge" weighted_capacity = "2" } launch_template { - id = aws_launch_template.example.id + id = aws_launch_template.example.id version = "1" } @@ -80,7 +80,7 @@ resource "aws_gamelift_game_server_group" "example" { } vpc_subnets = [ - "subnet-12345678", + "subnet-12345678", "subnet-23456789" ] @@ -91,6 +91,7 @@ resource "aws_gamelift_game_server_group" "example" { ``` ### Example IAM Role for Gamelift Game Server Group + ```hcl data "aws_partition" "current" {} @@ -118,7 +119,7 @@ resource "aws_iam_role" "example" { resource "aws_iam_role_policy_attachment" "example" { policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/GameLiftGameServerGroupPolicy" - role = aws_iam_role.example.name + role = aws_iam_role.example.name } ``` @@ -126,19 +127,19 @@ resource "aws_iam_role_policy_attachment" "example" { The following arguments are supported: -* `balancing_strategy` - (Optional) Indicates how GameLift FleetIQ balances the use of Spot Instances and On-Demand Instances. +* `balancing_strategy` - (Optional) Indicates how GameLift FleetIQ balances the use of Spot Instances and On-Demand Instances. Valid values: `SPOT_ONLY`, `SPOT_PREFERRED`, `ON_DEMAND_ONLY`. Defaults to `SPOT_PREFERRED`. -* `game_server_group_name` - (Required) Name of the game server group. +* `game_server_group_name` - (Required) Name of the game server group. This value is used to generate unique ARN identifiers for the EC2 Auto Scaling group and the GameLift FleetIQ game server group. -* `game_server_protection_policy` - (Optional) Indicates whether instances in the game server group are protected from early termination. - Unprotected instances that have active game servers running might be terminated during a scale-down event, - causing players to be dropped from the game. - Protected instances cannot be terminated while there are active game servers running except in the event +* `game_server_protection_policy` - (Optional) Indicates whether instances in the game server group are protected from early termination. + Unprotected instances that have active game servers running might be terminated during a scale-down event, + causing players to be dropped from the game. + Protected instances cannot be terminated while there are active game servers running except in the event of a forced game server group deletion. Valid values: `NO_PROTECTION`, `FULL_PROTECTION`. Defaults to `NO_PROTECTION`. -* `max_size` - (Required) The maximum number of instances allowed in the EC2 Auto Scaling group. +* `max_size` - (Required) The maximum number of instances allowed in the EC2 Auto Scaling group. During automatic scaling events, GameLift FleetIQ and EC2 do not scale up the group above this maximum. -* `min_size` - (Required) The minimum number of instances allowed in the EC2 Auto Scaling group. +* `min_size` - (Required) The minimum number of instances allowed in the EC2 Auto Scaling group. During automatic scaling events, GameLift FleetIQ and EC2 do not scale down the group below this minimum. * `role_arn` - (Required) ARN for an IAM role that allows Amazon GameLift to access your EC2 Auto Scaling groups. * `tags` - (Optional) Key-value map of resource tags @@ -146,34 +147,38 @@ The following arguments are supported: By default, all GameLift FleetIQ-supported Availability Zones are used. ### `auto_scaling_policy` + Configuration settings to define a scaling policy for the Auto Scaling group that is optimized for game hosting. -The scaling policy uses the metric `PercentUtilizedGameServers` to maintain a buffer of idle game servers that +The scaling policy uses the metric `PercentUtilizedGameServers` to maintain a buffer of idle game servers that can immediately accommodate new games and players. -* `estimated_instance_warmup` - (Optional) Length of time, in seconds, it takes for a new instance to start +* `estimated_instance_warmup` - (Optional) Length of time, in seconds, it takes for a new instance to start new game server processes and register with GameLift FleetIQ. - Specifying a warm-up time can be useful, particularly with game servers that take a long time to start up, + Specifying a warm-up time can be useful, particularly with game servers that take a long time to start up, because it avoids prematurely starting new instances. Defaults to `60`. #### `target_tracking_configuration` + Settings for a target-based scaling policy applied to Auto Scaling group. -These settings are used to create a target-based policy that tracks the GameLift FleetIQ metric `PercentUtilizedGameServers` +These settings are used to create a target-based policy that tracks the GameLift FleetIQ metric `PercentUtilizedGameServers` and specifies a target value for the metric. * `target_value` - (Required) Desired value to use with a game server group target-based scaling policy. ### `instance_definition` + The EC2 instance types and sizes to use in the Auto Scaling group. The instance definitions must specify at least two different instance types that are supported by GameLift FleetIQ. * `instance_type` - (Required) An EC2 instance type. -* `weighted_capacity` - (Optional) Instance weighting that indicates how much this instance type contributes - to the total capacity of a game server group. - Instance weights are used by GameLift FleetIQ to calculate the instance type's cost per unit hour and better identify +* `weighted_capacity` - (Optional) Instance weighting that indicates how much this instance type contributes + to the total capacity of a game server group. + Instance weights are used by GameLift FleetIQ to calculate the instance type's cost per unit hour and better identify the most cost-effective options. ### `launch_template` -The EC2 launch template that contains configuration settings and game server code to be deployed to all instances in the game server group. + +The EC2 launch template that contains configuration settings and game server code to be deployed to all instances in the game server group. You can specify the template using either the template name or ID. * `id` - (Optional) A unique identifier for an existing EC2 launch template. @@ -188,7 +193,6 @@ In addition to all arguments above, the following attributes are exported: * `arn` - The ARN of the Gamelift Game Server Group. * `auto_scaling_group_arn` - The ARN of the created EC2 Auto Scaling group. - ## Timeouts `aws_gamelift_game_server_group` provides the following From 522baf0b1b8168594dbb4d8e3ebc925b81fd5a41 Mon Sep 17 00:00:00 2001 From: Mykola Ulianytskyi Date: Tue, 9 Mar 2021 21:36:32 +0200 Subject: [PATCH 025/229] r/aws_gamelift_game_server_group: Fix formatting --- aws/resource_aws_gamelift_game_server_group_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aws/resource_aws_gamelift_game_server_group_test.go b/aws/resource_aws_gamelift_game_server_group_test.go index 59c614a6805..30c7120b226 100644 --- a/aws/resource_aws_gamelift_game_server_group_test.go +++ b/aws/resource_aws_gamelift_game_server_group_test.go @@ -926,7 +926,7 @@ resource "aws_gamelift_game_server_group" "test" { for_each = slice(tolist(data.aws_ec2_instance_type_offerings.available.instance_types), 0, 2) content { - instance_type = instance_definition.value + instance_type = instance_definition.value weighted_capacity = %[2]q } } @@ -1024,7 +1024,7 @@ resource "aws_gamelift_game_server_group" "test" { } launch_template { - id = aws_launch_template.test.id + id = aws_launch_template.test.id version = 1 } @@ -1142,7 +1142,7 @@ func testAccGameliftGameServerGroupConfigGameServerProtectionPolicy(rName string testAccGameliftGameServerGroupLaunchTemplateConfig(rName), fmt.Sprintf(` resource "aws_gamelift_game_server_group" "test" { - game_server_group_name = %[1]q + game_server_group_name = %[1]q game_server_protection_policy = %[2]q dynamic "instance_definition" { From d6d6a321f102b8ab2f2c169a620f73cc8606ce44 Mon Sep 17 00:00:00 2001 From: jamie lennox Date: Thu, 18 Nov 2021 14:10:46 +0000 Subject: [PATCH 026/229] New resource/aws_networkmanager_global_network --- internal/provider/provider.go | 3 + .../service/networkmanager/global_network.go | 278 ++++++++++++++++++ .../networkmanager/global_network_test.go | 227 ++++++++++++++ ...etworkmanager_global_network.html.markdown | 40 +++ 4 files changed, 548 insertions(+) create mode 100644 internal/service/networkmanager/global_network.go create mode 100644 internal/service/networkmanager/global_network_test.go create mode 100644 website/docs/r/networkmanager_global_network.html.markdown diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 417c3cba0bb..042ba10cc81 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -105,6 +105,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/service/mwaa" "github.com/hashicorp/terraform-provider-aws/internal/service/neptune" "github.com/hashicorp/terraform-provider-aws/internal/service/networkfirewall" + "github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager" "github.com/hashicorp/terraform-provider-aws/internal/service/opsworks" "github.com/hashicorp/terraform-provider-aws/internal/service/organizations" "github.com/hashicorp/terraform-provider-aws/internal/service/outposts" @@ -1357,6 +1358,8 @@ func Provider() *schema.Provider { "aws_networkfirewall_resource_policy": networkfirewall.ResourceResourcePolicy(), "aws_networkfirewall_rule_group": networkfirewall.ResourceRuleGroup(), + "aws_networkmanager_global_network": networkmanager.ResourceGlobalNetwork(), + "aws_opsworks_application": opsworks.ResourceApplication(), "aws_opsworks_custom_layer": opsworks.ResourceCustomLayer(), "aws_opsworks_ganglia_layer": opsworks.ResourceGangliaLayer(), diff --git a/internal/service/networkmanager/global_network.go b/internal/service/networkmanager/global_network.go new file mode 100644 index 00000000000..a8bf59ee916 --- /dev/null +++ b/internal/service/networkmanager/global_network.go @@ -0,0 +1,278 @@ +package networkmanager + +import ( + "fmt" + "log" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/internal/verify" +) + +func ResourceGlobalNetwork() *schema.Resource { + return &schema.Resource{ + Create: resourceGlobalNetworkCreate, + Read: resourceGlobalNetworkRead, + Update: resourceGlobalNetworkUpdate, + Delete: resourceGlobalNetworkDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Second), + Delete: schema.DefaultTimeout(30 * time.Second), + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + + "id": { + Type: schema.TypeString, + Computed: true, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + Default: "", + }, + + "tags": tftags.TagsSchema(), + "tags_all": tftags.TagsSchemaComputed(), + }, + + CustomizeDiff: verify.SetTagsDiff, + } +} + +func resourceGlobalNetworkCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).NetworkManagerConn + defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{}))) + + input := &networkmanager.CreateGlobalNetworkInput{} + + if v, ok := d.GetOk("description"); ok { + input.Description = aws.String(v.(string)) + } + + if len(tags) > 0 { + input.Tags = Tags(tags.IgnoreAWS()) + } + + log.Println("[DEBUG] Creating Global Network:", input) + output, err := conn.CreateGlobalNetwork(input) + if err != nil { + return fmt.Errorf("Error creating Global Network: %s", err) + } + + d.SetId(aws.StringValue(output.GlobalNetwork.GlobalNetworkId)) + + if err := waitForNetworkManagerGlobalNetworkCreation(conn, d.Id()); err != nil { + return fmt.Errorf("Error waiting for Global Network: %w", err) + } + + return resourceGlobalNetworkRead(d, meta) +} + +func resourceGlobalNetworkRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).NetworkManagerConn + defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig + + output, err := DescribeGlobalNetwork(conn, d.Id()) + + if tfawserr.ErrMessageContains(err, networkmanager.ErrCodeResourceNotFoundException, "") { + log.Printf("[WARN] No Global Networks by ID (%s) found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return fmt.Errorf("Error reading Global Network %s: %s", d.Id(), err) + } + + if output == nil { + log.Printf("[WARN] No Global Networks by ID (%s) found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if aws.StringValue(output.State) != networkmanager.ConnectionStateAvailable { + log.Printf("[WARN] Global Networks (%s) delet(ing|ed), removing from state", d.Id()) + d.SetId("") + return nil + } + + d.Set("arn", output.GlobalNetworkArn) + d.Set("description", output.Description) + + tags := KeyValueTags(output.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return fmt.Errorf("Error setting tags: %w", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("Error setting tags_all: %w", err) + } + + return nil + +} + +func resourceGlobalNetworkUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + if d.HasChanges("description") { + request := &networkmanager.UpdateGlobalNetworkInput{ + GlobalNetworkId: aws.String(d.Id()), + Description: aws.String(d.Get("description").(string)), + } + + log.Println("[DEBUG] Update Global Network request:", request) + _, err := conn.UpdateGlobalNetwork(request) + if err != nil { + if tfawserr.ErrMessageContains(err, networkmanager.ErrCodeResourceNotFoundException, "") { + log.Printf("[WARN] No Global Network by ID (%s) found", d.Id()) + d.SetId("") + return nil + } + return fmt.Errorf("Error updating Global Network %s: %s", d.Id(), err) + } + + } + + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") + + if err := UpdateTags(conn, d.Get("arn").(string), o, n); err != nil { + return fmt.Errorf("Error updating Global Network (%s) tags: %s", d.Id(), err) + } + } + + return resourceGlobalNetworkRead(d, meta) + +} + +func resourceGlobalNetworkDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + input := &networkmanager.DeleteGlobalNetworkInput{ + GlobalNetworkId: aws.String(d.Id()), + } + + log.Println("[DEBUG] Delete Global Network request:", input) + _, err := conn.DeleteGlobalNetwork(input) + if err != nil { + return fmt.Errorf("Error deleting Global Network: %s", err) + } + + if err := waitForNetworkManagerGlobalNetworkDeletion(conn, d.Id()); err != nil { + return fmt.Errorf("Error waiting for Global Network (%s) deletion: %s", d.Id(), err) + } + + return nil +} + +func networkManagerGlobalNetworkRefresh(conn *networkmanager.NetworkManager, globalNetworkId string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + networkManagerGlobalNetwork, err := DescribeGlobalNetwork(conn, globalNetworkId) + if tfawserr.ErrMessageContains(err, networkmanager.ErrCodeResourceNotFoundException, "") { + return nil, networkmanager.GlobalNetworkStateDeleting, nil + } + + if err != nil { + return nil, "", fmt.Errorf("Error reading Global Network (%s): %s", globalNetworkId, err) + } + + if networkManagerGlobalNetwork == nil { + return nil, networkmanager.GlobalNetworkStateDeleting, nil + } + + return networkManagerGlobalNetwork, aws.StringValue(networkManagerGlobalNetwork.State), nil + } +} + +func DescribeGlobalNetwork(conn *networkmanager.NetworkManager, globalNetworkID string) (*networkmanager.GlobalNetwork, error) { + request := &networkmanager.DescribeGlobalNetworksInput{ + GlobalNetworkIds: []*string{aws.String(globalNetworkID)}, + } + + log.Printf("[DEBUG] Reading Global Network (%s): %s", globalNetworkID, request) + for { + output, err := conn.DescribeGlobalNetworks(request) + + if err != nil { + return nil, err + } + + if output == nil || len(output.GlobalNetworks) == 0 { + return nil, nil + } + + for _, globalNetwork := range output.GlobalNetworks { + if globalNetwork == nil { + continue + } + + if aws.StringValue(globalNetwork.GlobalNetworkId) == globalNetworkID { + return globalNetwork, nil + } + } + + if aws.StringValue(output.NextToken) == "" { + break + } + + request.NextToken = output.NextToken + } + + return nil, nil +} + +func waitForNetworkManagerGlobalNetworkCreation(conn *networkmanager.NetworkManager, globalNetworkId string) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.GlobalNetworkStatePending}, + Target: []string{networkmanager.GlobalNetworkStateAvailable}, + Refresh: networkManagerGlobalNetworkRefresh(conn, globalNetworkId), + Timeout: 10 * time.Minute, + } + + log.Printf("[DEBUG] Waiting for Global Network (%s) creation", globalNetworkId) + _, err := stateConf.WaitForState() + + return err +} + +func waitForNetworkManagerGlobalNetworkDeletion(conn *networkmanager.NetworkManager, globalNetworkId string) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.GlobalNetworkStateAvailable}, + Target: []string{networkmanager.GlobalNetworkStateDeleting}, + Refresh: networkManagerGlobalNetworkRefresh(conn, globalNetworkId), + Timeout: 10 * time.Minute, + NotFoundChecks: 1, + } + + log.Printf("[DEBUG] Waiting for Global Network (%s) deletion", globalNetworkId) + _, err := stateConf.WaitForState() + + if tfresource.NotFound(err) { + return nil + } + + return err +} diff --git a/internal/service/networkmanager/global_network_test.go b/internal/service/networkmanager/global_network_test.go new file mode 100644 index 00000000000..21a8c0382c3 --- /dev/null +++ b/internal/service/networkmanager/global_network_test.go @@ -0,0 +1,227 @@ +package networkmanager_test + +import ( + "fmt" + "regexp" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/apigateway" + nm "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" + 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" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager" +) + +func TestAccNetworkManagerGlobalNetwork_basic(t *testing.T) { + var globalNetwork nm.GlobalNetwork + resourceName := "aws_networkmanager_global_network.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + Providers: acctest.Providers, + CheckDestroy: testAccCheckResourceGlobalNetworkDestroy, + Steps: []resource.TestStep{ + { + Config: testAccresourceGlobalNetworkConfig(), + Check: resource.ComposeTestCheckFunc( + testAccCheckResourceGlobalNetworkExists(resourceName, &globalNetwork), + acctest.MatchResourceAttrGlobalARN(resourceName, "arn", "networkmanager", regexp.MustCompile(`global-network/global-network-.+`)), + resource.TestCheckResourceAttr(resourceName, "description", ""), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccNetworkManagerGlobalNetwork_tags(t *testing.T) { + var globalNetwork nm.GlobalNetwork + resourceName := "aws_networkmanager_global_network.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + Providers: acctest.Providers, + CheckDestroy: testAccCheckResourceGlobalNetworkDestroy, + Steps: []resource.TestStep{ + { + Config: testAccresourceGlobalNetworkTagsConfig(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckResourceGlobalNetworkExists(resourceName, &globalNetwork), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), + ), + }, + { + Config: testAccresourceGlobalNetworkTagsConfig(rName, "key1", "value1"), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccresourceGlobalNetworkTags2Config(rName, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckResourceGlobalNetworkExists(resourceName, &globalNetwork), + resource.TestCheckResourceAttr(resourceName, "tags.%", "3"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), + ), + }, + { + Config: testAccresourceGlobalNetworkConfig(), + Check: resource.ComposeTestCheckFunc( + testAccCheckResourceGlobalNetworkExists(resourceName, &globalNetwork), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + }, + }) +} + +func TestAccNetworkManagerGlobalNetwork_description(t *testing.T) { + var globalNetwork nm.GlobalNetwork + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_networkmanager_global_network.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, apigateway.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckResourceGlobalNetworkDestroy, + Steps: []resource.TestStep{ + { + Config: testAccresourceGlobalNetworkDescriptionConfig(rName, "description1"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckResourceGlobalNetworkExists(resourceName, &globalNetwork), + resource.TestCheckResourceAttr(resourceName, "description", "description1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccresourceGlobalNetworkDescriptionConfig(rName, "description2"), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckResourceGlobalNetworkExists(resourceName, &globalNetwork), + resource.TestCheckResourceAttr(resourceName, "description", "description2"), + ), + }, + }, + }) +} + +func testAccCheckResourceGlobalNetworkDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_networkmanager_global_network" { + continue + } + + output, err := networkmanager.DescribeGlobalNetwork(conn, rs.Primary.ID) + + if tfawserr.ErrMessageContains(err, nm.ErrCodeResourceNotFoundException, "") { + continue + } + + if err != nil { + return err + } + + if output == nil { + continue + } + + if aws.StringValue(output.State) != nm.GlobalNetworkStateDeleting { + return fmt.Errorf("Network Manager Global Network (%s) still exists in non-deleted (%s) state", rs.Primary.ID, aws.StringValue(output.State)) + } + } + + return nil +} + +func testAccCheckResourceGlobalNetworkExists(resourceName string, globalNetwork *nm.GlobalNetwork) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No Network Manager Global Network ID is set") + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn + globalNetwork, err := networkmanager.DescribeGlobalNetwork(conn, rs.Primary.ID) + + if err != nil { + return nil + } + + if globalNetwork == nil { + return fmt.Errorf("Network Manager Global Network not found") + } + + if aws.StringValue(globalNetwork.State) != nm.GlobalNetworkStateAvailable { + return fmt.Errorf("Network Manager Global Netowrk (%s) exists in non-available (%s) state", rs.Primary.ID, aws.StringValue(globalNetwork.State)) + } + + return nil + + } +} + +func testAccresourceGlobalNetworkConfig() string { + return ` +resource "aws_networkmanager_global_network" "test" { } +` +} + +func testAccresourceGlobalNetworkDescriptionConfig(rName, description string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = %[2]q + + tags = { + Name = %[1]q + } +} +`, rName, description) +} + +func testAccresourceGlobalNetworkTagsConfig(rName, tagKey1, tagValue1 string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + %[2]q = %[3]q + } +} +`, rName, tagKey1, tagValue1) +} + +func testAccresourceGlobalNetworkTags2Config(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + %[2]q = %[3]q + %[4]q = %[5]q + } +} +`, rName, tagKey1, tagValue1, tagKey2, tagValue2) +} diff --git a/website/docs/r/networkmanager_global_network.html.markdown b/website/docs/r/networkmanager_global_network.html.markdown new file mode 100644 index 00000000000..5f7d425dda0 --- /dev/null +++ b/website/docs/r/networkmanager_global_network.html.markdown @@ -0,0 +1,40 @@ +--- +subcategory: "Transit Gateway Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_global_network" +description: |- + Provides a global network resource. +--- + +# Resource: aws_networkmanager_global_network + +Provides a global network resource. + +## Example Usage + +```hcl +resource "aws_networkmanager_global_network" "example" { + description = "example" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `description` - (Optional) Description of the Global Network. +* `tags` - (Optional) Key-value tags for the Global Network. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - Global Network Amazon Resource Name (ARN) + +## Import + +`aws_networkmanager_global_network` can be imported using the global network ID, e.g. + +``` +$ terraform import aws_networkmanager_global_network.example global-network-0d47f6t230mz46dy4 +``` \ No newline at end of file From 13c8114fc7956335fdf4c5ca46b53a4bbde623e4 Mon Sep 17 00:00:00 2001 From: jamie lennox Date: Thu, 18 Nov 2021 14:15:15 +0000 Subject: [PATCH 027/229] Adding changelog --- .changelog/21789.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/21789.txt diff --git a/.changelog/21789.txt b/.changelog/21789.txt new file mode 100644 index 00000000000..4ef1e831c56 --- /dev/null +++ b/.changelog/21789.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_networkmanager_global_network +``` \ No newline at end of file From ffd7a1640705ed358f5ae165d65ec47418e68855 Mon Sep 17 00:00:00 2001 From: jamie lennox Date: Fri, 19 Nov 2021 11:07:37 +0000 Subject: [PATCH 028/229] Fixing linter issues --- .../service/networkmanager/global_network_test.go | 13 ++++++++----- .../r/networkmanager_global_network.html.markdown | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/internal/service/networkmanager/global_network_test.go b/internal/service/networkmanager/global_network_test.go index 21a8c0382c3..fcc4a8ca0f0 100644 --- a/internal/service/networkmanager/global_network_test.go +++ b/internal/service/networkmanager/global_network_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/apigateway" nm "github.com/aws/aws-sdk-go/service/networkmanager" "github.com/hashicorp/aws-sdk-go-base/tfawserr" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" @@ -25,6 +24,7 @@ func TestAccNetworkManagerGlobalNetwork_basic(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, Providers: acctest.Providers, CheckDestroy: testAccCheckResourceGlobalNetworkDestroy, + ErrorCheck: acctest.ErrorCheck(t, nm.EndpointsID), Steps: []resource.TestStep{ { Config: testAccresourceGlobalNetworkConfig(), @@ -53,6 +53,7 @@ func TestAccNetworkManagerGlobalNetwork_tags(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, Providers: acctest.Providers, CheckDestroy: testAccCheckResourceGlobalNetworkDestroy, + ErrorCheck: acctest.ErrorCheck(t, nm.EndpointsID), Steps: []resource.TestStep{ { Config: testAccresourceGlobalNetworkTagsConfig(rName, "key1", "value1"), @@ -97,7 +98,7 @@ func TestAccNetworkManagerGlobalNetwork_description(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, - ErrorCheck: acctest.ErrorCheck(t, apigateway.EndpointsID), + ErrorCheck: acctest.ErrorCheck(t, nm.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckResourceGlobalNetworkDestroy, Steps: []resource.TestStep{ @@ -166,10 +167,12 @@ func testAccCheckResourceGlobalNetworkExists(resourceName string, globalNetwork } conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn - globalNetwork, err := networkmanager.DescribeGlobalNetwork(conn, rs.Primary.ID) + + var err error + globalNetwork, err = networkmanager.DescribeGlobalNetwork(conn, rs.Primary.ID) if err != nil { - return nil + return fmt.Errorf("Error describing Global Network: %s", err) } if globalNetwork == nil { @@ -177,7 +180,7 @@ func testAccCheckResourceGlobalNetworkExists(resourceName string, globalNetwork } if aws.StringValue(globalNetwork.State) != nm.GlobalNetworkStateAvailable { - return fmt.Errorf("Network Manager Global Netowrk (%s) exists in non-available (%s) state", rs.Primary.ID, aws.StringValue(globalNetwork.State)) + return fmt.Errorf("Network Manager Global Network (%s) exists in non-available (%s) state", rs.Primary.ID, aws.StringValue(globalNetwork.State)) } return nil diff --git a/website/docs/r/networkmanager_global_network.html.markdown b/website/docs/r/networkmanager_global_network.html.markdown index 5f7d425dda0..0dbab47db8a 100644 --- a/website/docs/r/networkmanager_global_network.html.markdown +++ b/website/docs/r/networkmanager_global_network.html.markdown @@ -12,7 +12,7 @@ Provides a global network resource. ## Example Usage -```hcl +```terraform resource "aws_networkmanager_global_network" "example" { description = "example" } From a59e3ac8ab2e1dbd18911f077a3939d95a3f84b5 Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Mon, 6 Dec 2021 19:27:31 +0000 Subject: [PATCH 029/229] networkmanager: move files to service package dir --- .../service/networkmanager/device.go | 0 .../service/networkmanager/device_data_source.go | 0 .../service/networkmanager/device_data_source_test.go | 0 .../service/networkmanager/device_test.go | 0 .../service/networkmanager/global_network.go | 0 .../service/networkmanager/global_network_data_source.go | 0 .../service/networkmanager/global_network_data_source_test.go | 0 .../service/networkmanager/global_network_test.go | 0 .../service/networkmanager/site.go | 0 .../service/networkmanager/site_data_source.go | 0 .../service/networkmanager/site_data_source_test.go | 0 .../service/networkmanager/site_test.go | 0 .../service/networkmanager/transit_gateway_registration.go | 0 .../service/networkmanager/transit_gateway_registration_test.go | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename aws/resource_aws_networkmanager_device.go => internal/service/networkmanager/device.go (100%) rename aws/data_source_aws_networkmanager_device.go => internal/service/networkmanager/device_data_source.go (100%) rename aws/data_source_aws_networkmanager_device_test.go => internal/service/networkmanager/device_data_source_test.go (100%) rename aws/resource_aws_networkmanager_device_test.go => internal/service/networkmanager/device_test.go (100%) rename aws/resource_aws_networkmanager_global_network.go => internal/service/networkmanager/global_network.go (100%) rename aws/data_source_aws_networkmanager_global_network.go => internal/service/networkmanager/global_network_data_source.go (100%) rename aws/data_source_aws_networkmanager_global_network_test.go => internal/service/networkmanager/global_network_data_source_test.go (100%) rename aws/resource_aws_networkmanager_global_network_test.go => internal/service/networkmanager/global_network_test.go (100%) rename aws/resource_aws_networkmanager_site.go => internal/service/networkmanager/site.go (100%) rename aws/data_source_aws_networkmanager_site.go => internal/service/networkmanager/site_data_source.go (100%) rename aws/data_source_aws_networkmanager_site_test.go => internal/service/networkmanager/site_data_source_test.go (100%) rename aws/resource_aws_networkmanager_site_test.go => internal/service/networkmanager/site_test.go (100%) rename aws/resource_aws_networkmanager_transit_gateway_registration.go => internal/service/networkmanager/transit_gateway_registration.go (100%) rename aws/resource_aws_networkmanager_transit_gateway_registration_test.go => internal/service/networkmanager/transit_gateway_registration_test.go (100%) diff --git a/aws/resource_aws_networkmanager_device.go b/internal/service/networkmanager/device.go similarity index 100% rename from aws/resource_aws_networkmanager_device.go rename to internal/service/networkmanager/device.go diff --git a/aws/data_source_aws_networkmanager_device.go b/internal/service/networkmanager/device_data_source.go similarity index 100% rename from aws/data_source_aws_networkmanager_device.go rename to internal/service/networkmanager/device_data_source.go diff --git a/aws/data_source_aws_networkmanager_device_test.go b/internal/service/networkmanager/device_data_source_test.go similarity index 100% rename from aws/data_source_aws_networkmanager_device_test.go rename to internal/service/networkmanager/device_data_source_test.go diff --git a/aws/resource_aws_networkmanager_device_test.go b/internal/service/networkmanager/device_test.go similarity index 100% rename from aws/resource_aws_networkmanager_device_test.go rename to internal/service/networkmanager/device_test.go diff --git a/aws/resource_aws_networkmanager_global_network.go b/internal/service/networkmanager/global_network.go similarity index 100% rename from aws/resource_aws_networkmanager_global_network.go rename to internal/service/networkmanager/global_network.go diff --git a/aws/data_source_aws_networkmanager_global_network.go b/internal/service/networkmanager/global_network_data_source.go similarity index 100% rename from aws/data_source_aws_networkmanager_global_network.go rename to internal/service/networkmanager/global_network_data_source.go diff --git a/aws/data_source_aws_networkmanager_global_network_test.go b/internal/service/networkmanager/global_network_data_source_test.go similarity index 100% rename from aws/data_source_aws_networkmanager_global_network_test.go rename to internal/service/networkmanager/global_network_data_source_test.go diff --git a/aws/resource_aws_networkmanager_global_network_test.go b/internal/service/networkmanager/global_network_test.go similarity index 100% rename from aws/resource_aws_networkmanager_global_network_test.go rename to internal/service/networkmanager/global_network_test.go diff --git a/aws/resource_aws_networkmanager_site.go b/internal/service/networkmanager/site.go similarity index 100% rename from aws/resource_aws_networkmanager_site.go rename to internal/service/networkmanager/site.go diff --git a/aws/data_source_aws_networkmanager_site.go b/internal/service/networkmanager/site_data_source.go similarity index 100% rename from aws/data_source_aws_networkmanager_site.go rename to internal/service/networkmanager/site_data_source.go diff --git a/aws/data_source_aws_networkmanager_site_test.go b/internal/service/networkmanager/site_data_source_test.go similarity index 100% rename from aws/data_source_aws_networkmanager_site_test.go rename to internal/service/networkmanager/site_data_source_test.go diff --git a/aws/resource_aws_networkmanager_site_test.go b/internal/service/networkmanager/site_test.go similarity index 100% rename from aws/resource_aws_networkmanager_site_test.go rename to internal/service/networkmanager/site_test.go diff --git a/aws/resource_aws_networkmanager_transit_gateway_registration.go b/internal/service/networkmanager/transit_gateway_registration.go similarity index 100% rename from aws/resource_aws_networkmanager_transit_gateway_registration.go rename to internal/service/networkmanager/transit_gateway_registration.go diff --git a/aws/resource_aws_networkmanager_transit_gateway_registration_test.go b/internal/service/networkmanager/transit_gateway_registration_test.go similarity index 100% rename from aws/resource_aws_networkmanager_transit_gateway_registration_test.go rename to internal/service/networkmanager/transit_gateway_registration_test.go From b71e15d20a40eba048afc158267b3c763e031242 Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Mon, 6 Dec 2021 19:29:15 +0000 Subject: [PATCH 030/229] networkmannager: flex funcs --- internal/service/networkmanager/device.go | 6 ++-- internal/service/networkmanager/flex.go | 34 +++++++++++++++++++ internal/service/networkmanager/site.go | 6 ++-- .../networkmanager/site_data_source.go | 2 +- 4 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 internal/service/networkmanager/flex.go diff --git a/internal/service/networkmanager/device.go b/internal/service/networkmanager/device.go index 56a4a5ae7a5..8872e0d5757 100644 --- a/internal/service/networkmanager/device.go +++ b/internal/service/networkmanager/device.go @@ -109,7 +109,7 @@ func resourceAwsNetworkManagerDeviceCreate(d *schema.ResourceData, meta interfac input := &networkmanager.CreateDeviceInput{ Description: aws.String(d.Get("description").(string)), GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), - Location: expandNetworkManagerLocation(d.Get("location").([]interface{})), + Location: expandLocation(d.Get("location").([]interface{})), Model: aws.String(d.Get("model").(string)), SerialNumber: aws.String(d.Get("serial_number").(string)), SiteId: aws.String(d.Get("site_id").(string)), @@ -178,7 +178,7 @@ func resourceAwsNetworkManagerDeviceRead(d *schema.ResourceData, meta interface{ d.Set("type", device.Type) d.Set("vendor", device.Vendor) - if err := d.Set("location", flattenNetworkManagerLocation(device.Location)); err != nil { + if err := d.Set("location", flattenLocation(device.Location)); err != nil { return fmt.Errorf("error setting location: %s", err) } @@ -197,7 +197,7 @@ func resourceAwsNetworkManagerDeviceUpdate(d *schema.ResourceData, meta interfac Description: aws.String(d.Get("description").(string)), DeviceId: aws.String(d.Id()), GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), - Location: expandNetworkManagerLocation(d.Get("location").([]interface{})), + Location: expandLocation(d.Get("location").([]interface{})), Model: aws.String(d.Get("model").(string)), SerialNumber: aws.String(d.Get("serial_number").(string)), SiteId: aws.String(d.Get("site_id").(string)), diff --git a/internal/service/networkmanager/flex.go b/internal/service/networkmanager/flex.go new file mode 100644 index 00000000000..57875298546 --- /dev/null +++ b/internal/service/networkmanager/flex.go @@ -0,0 +1,34 @@ +package networkmanager + +import ( + "strings" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func flattenLocation(location *networkmanager.Location) []interface{} { + if location == nil { + return []interface{}{} + } + m := map[string]interface{}{ + "address": aws.StringValue(location.Address), + "latitude": aws.StringValue(location.Latitude), + "longitude": aws.StringValue(location.Longitude), + } + return []interface{}{m} +} + +func expandLocation(l []interface{}) *networkmanager.Location { + if len(l) == 0 || l[0] == nil { + return nil + } + m := l[0].(map[string]interface{}) + logs := &networkmanager.Location{ + Address: aws.String(m["address"].(string)), + Latitude: aws.String(m["latitude"].(string)), + Longitude: aws.String(m["longitude"].(string)), + } + return logs +} diff --git a/internal/service/networkmanager/site.go b/internal/service/networkmanager/site.go index 6969470ccc5..f6e1bd26593 100644 --- a/internal/service/networkmanager/site.go +++ b/internal/service/networkmanager/site.go @@ -89,7 +89,7 @@ func resourceAwsNetworkManagerSiteCreate(d *schema.ResourceData, meta interface{ input := &networkmanager.CreateSiteInput{ Description: aws.String(d.Get("description").(string)), GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), - Location: expandNetworkManagerLocation(d.Get("location").([]interface{})), + Location: expandLocation(d.Get("location").([]interface{})), Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().NetworkmanagerTags(), } @@ -148,7 +148,7 @@ func resourceAwsNetworkManagerSiteRead(d *schema.ResourceData, meta interface{}) d.Set("arn", site.SiteArn) d.Set("description", site.Description) - if err := d.Set("location", flattenNetworkManagerLocation(site.Location)); err != nil { + if err := d.Set("location", flattenLocation(site.Location)); err != nil { return fmt.Errorf("error setting location: %s", err) } @@ -166,7 +166,7 @@ func resourceAwsNetworkManagerSiteUpdate(d *schema.ResourceData, meta interface{ request := &networkmanager.UpdateSiteInput{ Description: aws.String(d.Get("description").(string)), GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), - Location: expandNetworkManagerLocation(d.Get("location").([]interface{})), + Location: expandLocation(d.Get("location").([]interface{})), SiteId: aws.String(d.Id()), } diff --git a/internal/service/networkmanager/site_data_source.go b/internal/service/networkmanager/site_data_source.go index 95337e6fd7d..5adf92456ba 100644 --- a/internal/service/networkmanager/site_data_source.go +++ b/internal/service/networkmanager/site_data_source.go @@ -110,7 +110,7 @@ func dataSourceAwsNetworkManagerSiteRead(d *schema.ResourceData, meta interface{ d.Set("description", site.Description) d.Set("arn", site.SiteArn) - if err := d.Set("location", flattenNetworkManagerLocation(site.Location)); err != nil { + if err := d.Set("location", flattenLocation(site.Location)); err != nil { return fmt.Errorf("error setting location: %s", err) } if err := d.Set("tags", keyvaluetags.NetworkmanagerKeyValueTags(site.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { From 43bcd65c09f84a36da99f9c5af9658745374e57e Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Mon, 6 Dec 2021 20:03:03 +0000 Subject: [PATCH 031/229] networkmanager: appropriate function names --- internal/service/networkmanager/device.go | 22 ++++---- .../networkmanager/device_data_source.go | 6 +-- .../networkmanager/device_data_source_test.go | 8 +-- .../service/networkmanager/device_test.go | 52 +++++++++---------- .../service/networkmanager/global_network.go | 30 +++++------ .../global_network_data_source.go | 6 +-- .../global_network_data_source_test.go | 8 +-- .../networkmanager/global_network_test.go | 46 ++++++++-------- internal/service/networkmanager/site.go | 24 ++++----- .../networkmanager/site_data_source.go | 6 +-- .../networkmanager/site_data_source_test.go | 8 +-- internal/service/networkmanager/site_test.go | 52 +++++++++---------- .../transit_gateway_registration.go | 20 +++---- .../transit_gateway_registration_test.go | 30 +++++------ 14 files changed, 159 insertions(+), 159 deletions(-) diff --git a/internal/service/networkmanager/device.go b/internal/service/networkmanager/device.go index 8872e0d5757..6a0ddc68b8a 100644 --- a/internal/service/networkmanager/device.go +++ b/internal/service/networkmanager/device.go @@ -14,12 +14,12 @@ import ( "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) -func resourceAwsNetworkManagerDevice() *schema.Resource { +func ResourceDevice() *schema.Resource { return &schema.Resource{ - Create: resourceAwsNetworkManagerDeviceCreate, - Read: resourceAwsNetworkManagerDeviceRead, - Update: resourceAwsNetworkManagerDeviceUpdate, - Delete: resourceAwsNetworkManagerDeviceDelete, + Create: ResourceDeviceCreate, + Read: ResourceDeviceRead, + Update: ResourceDeviceUpdate, + Delete: ResourceDeviceDelete, Importer: &schema.ResourceImporter{ State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { d.Set("arn", d.Id()) @@ -103,7 +103,7 @@ func resourceAwsNetworkManagerDevice() *schema.Resource { } } -func resourceAwsNetworkManagerDeviceCreate(d *schema.ResourceData, meta interface{}) error { +func ResourceDeviceCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn input := &networkmanager.CreateDeviceInput{ @@ -139,10 +139,10 @@ func resourceAwsNetworkManagerDeviceCreate(d *schema.ResourceData, meta interfac return fmt.Errorf("error waiting for Network Manager Device (%s) availability: %s", d.Id(), err) } - return resourceAwsNetworkManagerDeviceRead(d, meta) + return ResourceDeviceRead(d, meta) } -func resourceAwsNetworkManagerDeviceRead(d *schema.ResourceData, meta interface{}) error { +func ResourceDeviceRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig @@ -189,7 +189,7 @@ func resourceAwsNetworkManagerDeviceRead(d *schema.ResourceData, meta interface{ return nil } -func resourceAwsNetworkManagerDeviceUpdate(d *schema.ResourceData, meta interface{}) error { +func ResourceDeviceUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn if d.HasChanges("description", "location", "model", "serial_number", "site_id", "type", "vendor") { @@ -222,7 +222,7 @@ func resourceAwsNetworkManagerDeviceUpdate(d *schema.ResourceData, meta interfac return nil } -func resourceAwsNetworkManagerDeviceDelete(d *schema.ResourceData, meta interface{}) error { +func ResourceDeviceDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn input := &networkmanager.DeleteDeviceInput{ @@ -261,7 +261,7 @@ func resourceAwsNetworkManagerDeviceDelete(d *schema.ResourceData, meta interfac return fmt.Errorf("error deleting Network Manager Device: %s", err) } - if err := waitForNetworkManagerDeviceDeletion(conn, d.Get("global_network_id").(string), d.Id()); err != nil { + if err := waitForDeviceDeletion(conn, d.Get("global_network_id").(string), d.Id()); err != nil { return fmt.Errorf("error waiting for Network Manager Device (%s) deletion: %s", d.Id(), err) } diff --git a/internal/service/networkmanager/device_data_source.go b/internal/service/networkmanager/device_data_source.go index 7923910030b..c1128addec8 100644 --- a/internal/service/networkmanager/device_data_source.go +++ b/internal/service/networkmanager/device_data_source.go @@ -11,9 +11,9 @@ import ( "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) -func dataSourceAwsNetworkManagerDevice() *schema.Resource { +func DataSourceDevice() *schema.Resource { return &schema.Resource{ - Read: dataSourceAwsNetworkManagerDeviceRead, + Read: DataSourceDeviceRead, Schema: map[string]*schema.Schema{ "arn": { @@ -77,7 +77,7 @@ func dataSourceAwsNetworkManagerDevice() *schema.Resource { } } -func dataSourceAwsNetworkManagerDeviceRead(d *schema.ResourceData, meta interface{}) error { +func DataSourceDeviceRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig diff --git a/internal/service/networkmanager/device_data_source_test.go b/internal/service/networkmanager/device_data_source_test.go index 94cd621cff5..7d93d94ea1d 100644 --- a/internal/service/networkmanager/device_data_source_test.go +++ b/internal/service/networkmanager/device_data_source_test.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) -func TestAccDataSourceAWSNetworkManagerDevice_basic(t *testing.T) { +func TestAccDataSourceDevice_basic(t *testing.T) { dataSourceName := "data.aws_networkmanager_device.test" dataSourceByIdName := "data.aws_networkmanager_device.test_by_id" dataSourceBySiteIdName := "data.aws_networkmanager_device.test_by_site_id" @@ -22,10 +22,10 @@ func TestAccDataSourceAWSNetworkManagerDevice_basic(t *testing.T) { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckAwsNetworkManagerDeviceDestroy, + CheckDestroy: testAccCheckAwsDeviceDestroy, Steps: []resource.TestStep{ { - Config: testAccDataSourceAwsNetworkManagerDeviceConfig(), + Config: testAccDataSourceDeviceConfig(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrPair(dataSourceName, "id", resourceName, "id"), resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"), @@ -51,7 +51,7 @@ func TestAccDataSourceAWSNetworkManagerDevice_basic(t *testing.T) { }) } -func testAccDataSourceAwsNetworkManagerDeviceConfig() string { +func testAccDataSourceDeviceConfig() string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { description = "test" diff --git a/internal/service/networkmanager/device_test.go b/internal/service/networkmanager/device_test.go index a3c5e8433d3..a127315688c 100644 --- a/internal/service/networkmanager/device_test.go +++ b/internal/service/networkmanager/device_test.go @@ -15,11 +15,11 @@ import ( func init() { resource.AddTestSweepers("aws_networkmanager_device", &resource.Sweeper{ Name: "aws_networkmanager_device", - F: testSweepNetworkManagerDevice, + F: testSweepDevice, }) } -func testSweepNetworkManagerDevice(region string) error { +func testSweepDevice(region string) error { client, err := sharedClientForRegion(region) if err != nil { return fmt.Errorf("error getting client: %s", err) @@ -51,7 +51,7 @@ func testSweepNetworkManagerDevice(region string) error { continue } - if err := waitForNetworkManagerDeviceDeletion(conn, globalNetworkID, id); err != nil { + if err := waitForDeviceDeletion(conn, globalNetworkID, id); err != nil { sweeperErr := fmt.Errorf("error waiting for Network Manager Device (%s) deletion: %s", id, err) log.Printf("[ERROR] %s", sweeperErr) sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) @@ -72,7 +72,7 @@ func testSweepNetworkManagerDevice(region string) error { return sweeperErrs.ErrorOrNil() } -func TestAccAWSNetworkManagerDevice_basic(t *testing.T) { +func TestAccDevice_basic(t *testing.T) { resourceName := "aws_networkmanager_device.test" siteResourceName := "aws_networkmanager_site.test" site2ResourceName := "aws_networkmanager_site.test2" @@ -81,12 +81,12 @@ func TestAccAWSNetworkManagerDevice_basic(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckAwsNetworkManagerDeviceDestroy, + CheckDestroy: testAccCheckAwsDeviceDestroy, Steps: []resource.TestStep{ { - Config: testAccNetworkManagerDeviceConfig("test"), + Config: testAccDeviceConfig("test"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerDeviceExists(resourceName), + testAccCheckAwsDeviceExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "arn"), resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetworkResourceName, "id"), resource.TestCheckResourceAttrPair(resourceName, "site_id", siteResourceName, "id"), @@ -101,13 +101,13 @@ func TestAccAWSNetworkManagerDevice_basic(t *testing.T) { { ResourceName: resourceName, ImportState: true, - ImportStateIdFunc: testAccAWSNetworkManagerDeviceImportStateIdFunc(resourceName), + ImportStateIdFunc: testAccDeviceImportStateIdFunc(resourceName), ImportStateVerify: true, }, { - Config: testAccNetworkManagerDeviceConfig_Update("test updated", "def", "456", "home device", "othercompany", "18.0029784", "-76.7897987"), + Config: testAccDeviceConfig_Update("test updated", "def", "456", "home device", "othercompany", "18.0029784", "-76.7897987"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerDeviceExists(resourceName), + testAccCheckAwsDeviceExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "arn"), resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetworkResourceName, "id"), resource.TestCheckResourceAttrPair(resourceName, "site_id", site2ResourceName, "id"), @@ -126,19 +126,19 @@ func TestAccAWSNetworkManagerDevice_basic(t *testing.T) { }) } -func TestAccAWSNetworkManagerDevice_tags(t *testing.T) { +func TestAccDevice_tags(t *testing.T) { resourceName := "aws_networkmanager_device.test" description := "test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckAwsNetworkManagerDeviceDestroy, + CheckDestroy: testAccCheckAwsDeviceDestroy, Steps: []resource.TestStep{ { - Config: testAccNetworkManagerDeviceConfigTags1(description, "key1", "value1"), + Config: testAccDeviceConfigTags1(description, "key1", "value1"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerDeviceExists(resourceName), + testAccCheckAwsDeviceExists(resourceName), resource.TestCheckResourceAttr(resourceName, "description", "test"), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), @@ -147,13 +147,13 @@ func TestAccAWSNetworkManagerDevice_tags(t *testing.T) { { ResourceName: resourceName, ImportState: true, - ImportStateIdFunc: testAccAWSNetworkManagerDeviceImportStateIdFunc(resourceName), + ImportStateIdFunc: testAccDeviceImportStateIdFunc(resourceName), ImportStateVerify: true, }, { - Config: testAccNetworkManagerDeviceConfigTags2(description, "key1", "value1updated", "key2", "value2"), + Config: testAccDeviceConfigTags2(description, "key1", "value1updated", "key2", "value2"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerDeviceExists(resourceName), + testAccCheckAwsDeviceExists(resourceName), resource.TestCheckResourceAttr(resourceName, "description", "test"), resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), @@ -161,9 +161,9 @@ func TestAccAWSNetworkManagerDevice_tags(t *testing.T) { ), }, { - Config: testAccNetworkManagerDeviceConfigTags1(description, "key2", "value2"), + Config: testAccDeviceConfigTags1(description, "key2", "value2"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerDeviceExists(resourceName), + testAccCheckAwsDeviceExists(resourceName), resource.TestCheckResourceAttr(resourceName, "description", "test"), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), @@ -173,7 +173,7 @@ func TestAccAWSNetworkManagerDevice_tags(t *testing.T) { }) } -func testAccCheckAwsNetworkManagerDeviceDestroy(s *terraform.State) error { +func testAccCheckAwsDeviceDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn for _, rs := range s.RootModule().Resources { @@ -199,7 +199,7 @@ func testAccCheckAwsNetworkManagerDeviceDestroy(s *terraform.State) error { return nil } -func testAccCheckAwsNetworkManagerDeviceExists(name string) resource.TestCheckFunc { +func testAccCheckAwsDeviceExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[name] if !ok { @@ -226,7 +226,7 @@ func testAccCheckAwsNetworkManagerDeviceExists(name string) resource.TestCheckFu } } -func testAccNetworkManagerDeviceConfig(description string) string { +func testAccDeviceConfig(description string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { description = "test" @@ -249,7 +249,7 @@ resource "aws_networkmanager_device" "test" { `, description) } -func testAccNetworkManagerDeviceConfigTags1(description, tagKey1, tagValue1 string) string { +func testAccDeviceConfigTags1(description, tagKey1, tagValue1 string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { description = "test" @@ -272,7 +272,7 @@ resource "aws_networkmanager_device" "test" { `, description, tagKey1, tagValue1) } -func testAccNetworkManagerDeviceConfigTags2(description, tagKey1, tagValue1, tagKey2, tagValue2 string) string { +func testAccDeviceConfigTags2(description, tagKey1, tagValue1, tagKey2, tagValue2 string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { description = "test" @@ -295,7 +295,7 @@ resource "aws_networkmanager_device" "test" { `, description, tagKey1, tagValue1, tagKey2, tagValue2) } -func testAccNetworkManagerDeviceConfig_Update(description, model, serial_number, device_type, vendor, latitude, longitude string) string { +func testAccDeviceConfig_Update(description, model, serial_number, device_type, vendor, latitude, longitude string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { description = "test" @@ -328,7 +328,7 @@ resource "aws_networkmanager_device" "test" { `, description, model, serial_number, device_type, vendor, latitude, longitude) } -func testAccAWSNetworkManagerDeviceImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { +func testAccDeviceImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { return func(s *terraform.State) (string, error) { rs, ok := s.RootModule().Resources[resourceName] if !ok { diff --git a/internal/service/networkmanager/global_network.go b/internal/service/networkmanager/global_network.go index ea83de6a5df..ffc207ef40c 100644 --- a/internal/service/networkmanager/global_network.go +++ b/internal/service/networkmanager/global_network.go @@ -12,12 +12,12 @@ import ( "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) -func resourceAwsNetworkManagerGlobalNetwork() *schema.Resource { +func ResourceGlobalNetwork() *schema.Resource { return &schema.Resource{ - Create: resourceAwsNetworkManagerGlobalNetworkCreate, - Read: resourceAwsNetworkManagerGlobalNetworkRead, - Update: resourceAwsNetworkManagerGlobalNetworkUpdate, - Delete: resourceAwsNetworkManagerGlobalNetworkDelete, + Create: ResourceGlobalNetworkCreate, + Read: ResourceGlobalNetworkRead, + Update: ResourceGlobalNetworkUpdate, + Delete: ResourceGlobalNetworkDelete, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, @@ -36,7 +36,7 @@ func resourceAwsNetworkManagerGlobalNetwork() *schema.Resource { } } -func resourceAwsNetworkManagerGlobalNetworkCreate(d *schema.ResourceData, meta interface{}) error { +func ResourceGlobalNetworkCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn input := &networkmanager.CreateGlobalNetworkInput{ @@ -82,10 +82,10 @@ func resourceAwsNetworkManagerGlobalNetworkCreate(d *schema.ResourceData, meta i return fmt.Errorf("error waiting for networkmanager Global Network (%s) availability: %s", d.Id(), err) } - return resourceAwsNetworkManagerGlobalNetworkRead(d, meta) + return ResourceGlobalNetworkRead(d, meta) } -func resourceAwsNetworkManagerGlobalNetworkRead(d *schema.ResourceData, meta interface{}) error { +func ResourceGlobalNetworkRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig @@ -123,7 +123,7 @@ func resourceAwsNetworkManagerGlobalNetworkRead(d *schema.ResourceData, meta int return nil } -func resourceAwsNetworkManagerGlobalNetworkUpdate(d *schema.ResourceData, meta interface{}) error { +func ResourceGlobalNetworkUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn if d.HasChange("description") { @@ -149,7 +149,7 @@ func resourceAwsNetworkManagerGlobalNetworkUpdate(d *schema.ResourceData, meta i return nil } -func resourceAwsNetworkManagerGlobalNetworkDelete(d *schema.ResourceData, meta interface{}) error { +func ResourceGlobalNetworkDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn input := &networkmanager.DeleteGlobalNetworkInput{ @@ -199,7 +199,7 @@ func resourceAwsNetworkManagerGlobalNetworkDelete(d *schema.ResourceData, meta i return fmt.Errorf("error deleting networkmanager Global Network: %s", err) } - if err := waitForNetworkManagerGlobalNetworkDeletion(conn, d.Id()); err != nil { + if err := waitForGlobalNetworkDeletion(conn, d.Id()); err != nil { return fmt.Errorf("error waiting for networkmanager Global Network (%s) deletion: %s", d.Id(), err) } @@ -215,7 +215,7 @@ func networkmanagerGlobalNetworkRefreshFunc(conn *networkmanager.NetworkManager, } if err != nil { - return nil, "", fmt.Errorf("error reading NetworkManager Global Network (%s): %s", globalNetworkID, err) + return nil, "", fmt.Errorf("error reading Global Network (%s): %s", globalNetworkID, err) } if globalNetwork == nil { @@ -231,7 +231,7 @@ func networkmanagerDescribeGlobalNetwork(conn *networkmanager.NetworkManager, gl GlobalNetworkIds: []*string{aws.String(globalNetworkID)}, } - log.Printf("[DEBUG] Reading NetworkManager Global Network (%s): %s", globalNetworkID, input) + log.Printf("[DEBUG] Reading Global Network (%s): %s", globalNetworkID, input) for { output, err := conn.DescribeGlobalNetworks(input) @@ -263,7 +263,7 @@ func networkmanagerDescribeGlobalNetwork(conn *networkmanager.NetworkManager, gl return nil, nil } -func waitForNetworkManagerGlobalNetworkDeletion(conn *networkmanager.NetworkManager, globalNetworkID string) error { +func waitForGlobalNetworkDeletion(conn *networkmanager.NetworkManager, globalNetworkID string) error { stateConf := &resource.StateChangeConf{ Pending: []string{ networkmanager.GlobalNetworkStateAvailable, @@ -275,7 +275,7 @@ func waitForNetworkManagerGlobalNetworkDeletion(conn *networkmanager.NetworkMana NotFoundChecks: 1, } - log.Printf("[DEBUG] Waiting for NetworkManager Global Network (%s) deletion", globalNetworkID) + log.Printf("[DEBUG] Waiting for Global Network (%s) deletion", globalNetworkID) _, err := stateConf.WaitForState() if isResourceNotFoundError(err) { diff --git a/internal/service/networkmanager/global_network_data_source.go b/internal/service/networkmanager/global_network_data_source.go index cfb6eaac4ed..f0b8eb9275f 100644 --- a/internal/service/networkmanager/global_network_data_source.go +++ b/internal/service/networkmanager/global_network_data_source.go @@ -11,9 +11,9 @@ import ( "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) -func dataSourceAwsNetworkManagerGlobalNetwork() *schema.Resource { +func DataSourceGlobalNetwork() *schema.Resource { return &schema.Resource{ - Read: dataSourceAwsNetworkManagerGlobalNetworkRead, + Read: DataSourceGlobalNetworkRead, Schema: map[string]*schema.Schema{ "arn": { @@ -33,7 +33,7 @@ func dataSourceAwsNetworkManagerGlobalNetwork() *schema.Resource { } } -func dataSourceAwsNetworkManagerGlobalNetworkRead(d *schema.ResourceData, meta interface{}) error { +func DataSourceGlobalNetworkRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig diff --git a/internal/service/networkmanager/global_network_data_source_test.go b/internal/service/networkmanager/global_network_data_source_test.go index 77b6941cc64..c4988a4a1d8 100644 --- a/internal/service/networkmanager/global_network_data_source_test.go +++ b/internal/service/networkmanager/global_network_data_source_test.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) -func TestAccDataSourceAWSNetworkManagerGlobalNetwork_basic(t *testing.T) { +func TestAccDataSourceGlobalNetwork_basic(t *testing.T) { dataSourceByIdName := "data.aws_networkmanager_global_network.test_by_id" dataSourceByTagsName := "data.aws_networkmanager_global_network.test_by_tags" resourceName := "aws_networkmanager_global_network.test" @@ -18,10 +18,10 @@ func TestAccDataSourceAWSNetworkManagerGlobalNetwork_basic(t *testing.T) { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckAwsNetworkManagerGlobalNetworkDestroy, + CheckDestroy: testAccCheckAwsGlobalNetworkDestroy, Steps: []resource.TestStep{ { - Config: testAccDataSourceAwsNetworkManagerGlobalNetworkConfig(), + Config: testAccDataSourceGlobalNetworkConfig(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrPair(dataSourceByIdName, "id", resourceName, "id"), resource.TestCheckResourceAttrPair(dataSourceByIdName, "arn", resourceName, "arn"), @@ -38,7 +38,7 @@ func TestAccDataSourceAWSNetworkManagerGlobalNetwork_basic(t *testing.T) { }) } -func testAccDataSourceAwsNetworkManagerGlobalNetworkConfig() string { +func testAccDataSourceGlobalNetworkConfig() string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { description = "test" diff --git a/internal/service/networkmanager/global_network_test.go b/internal/service/networkmanager/global_network_test.go index 5c4427acc64..7b51e423f58 100644 --- a/internal/service/networkmanager/global_network_test.go +++ b/internal/service/networkmanager/global_network_test.go @@ -16,11 +16,11 @@ import ( func init() { resource.AddTestSweepers("aws_networkmanager_global_network", &resource.Sweeper{ Name: "aws_networkmanager_global_network", - F: testSweepNetworkManagerGlobalNetwork, + F: testSweepGlobalNetwork, }) } -func testSweepNetworkManagerGlobalNetwork(region string) error { +func testSweepGlobalNetwork(region string) error { client, err := sharedClientForRegion(region) if err != nil { return fmt.Errorf("error getting client: %s", err) @@ -51,7 +51,7 @@ func testSweepNetworkManagerGlobalNetwork(region string) error { continue } - if err := waitForNetworkManagerGlobalNetworkDeletion(conn, id); err != nil { + if err := waitForGlobalNetworkDeletion(conn, id); err != nil { sweeperErr := fmt.Errorf("error waiting for Network Manager Global Network (%s) deletion: %s", id, err) log.Printf("[ERROR] %s", sweeperErr) sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) @@ -72,18 +72,18 @@ func testSweepNetworkManagerGlobalNetwork(region string) error { return sweeperErrs.ErrorOrNil() } -func TestAccAWSNetworkManagerGlobalNetwork_basic(t *testing.T) { +func TestAccGlobalNetwork_basic(t *testing.T) { resourceName := "aws_networkmanager_global_network.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckAwsNetworkManagerGlobalNetworkDestroy, + CheckDestroy: testAccCheckAwsGlobalNetworkDestroy, Steps: []resource.TestStep{ { - Config: testAccNetworkManagerGlobalNetworkConfig("test"), + Config: testAccGlobalNetworkConfig("test"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerGlobalNetworkExists(resourceName), + testAccCheckAwsGlobalNetworkExists(resourceName), testAccMatchResourceAttrGlobalARN(resourceName, "arn", "networkmanager", regexp.MustCompile(`global-network/global-network-.+`)), resource.TestCheckResourceAttr(resourceName, "description", "test"), ), @@ -94,9 +94,9 @@ func TestAccAWSNetworkManagerGlobalNetwork_basic(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccNetworkManagerGlobalNetworkConfig_Update("test updated"), + Config: testAccGlobalNetworkConfig_Update("test updated"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerGlobalNetworkExists(resourceName), + testAccCheckAwsGlobalNetworkExists(resourceName), testAccMatchResourceAttrGlobalARN(resourceName, "arn", "networkmanager", regexp.MustCompile(`global-network/global-network-.+`)), resource.TestCheckResourceAttr(resourceName, "description", "test updated"), ), @@ -105,19 +105,19 @@ func TestAccAWSNetworkManagerGlobalNetwork_basic(t *testing.T) { }) } -func TestAccAWSNetworkManagerGlobalNetwork_tags(t *testing.T) { +func TestAccGlobalNetwork_tags(t *testing.T) { resourceName := "aws_networkmanager_global_network.test" description := "test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckAwsNetworkManagerGlobalNetworkDestroy, + CheckDestroy: testAccCheckAwsGlobalNetworkDestroy, Steps: []resource.TestStep{ { - Config: testAccNetworkManagerGlobalNetworkConfigTags1(description, "key1", "value1"), + Config: testAccGlobalNetworkConfigTags1(description, "key1", "value1"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerGlobalNetworkExists(resourceName), + testAccCheckAwsGlobalNetworkExists(resourceName), resource.TestCheckResourceAttr(resourceName, "description", "test"), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), @@ -129,9 +129,9 @@ func TestAccAWSNetworkManagerGlobalNetwork_tags(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccNetworkManagerGlobalNetworkConfigTags2(description, "key1", "value1updated", "key2", "value2"), + Config: testAccGlobalNetworkConfigTags2(description, "key1", "value1updated", "key2", "value2"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerGlobalNetworkExists(resourceName), + testAccCheckAwsGlobalNetworkExists(resourceName), resource.TestCheckResourceAttr(resourceName, "description", "test"), resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), @@ -139,9 +139,9 @@ func TestAccAWSNetworkManagerGlobalNetwork_tags(t *testing.T) { ), }, { - Config: testAccNetworkManagerGlobalNetworkConfigTags1(description, "key2", "value2"), + Config: testAccGlobalNetworkConfigTags1(description, "key2", "value2"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerGlobalNetworkExists(resourceName), + testAccCheckAwsGlobalNetworkExists(resourceName), resource.TestCheckResourceAttr(resourceName, "description", "test"), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), @@ -151,7 +151,7 @@ func TestAccAWSNetworkManagerGlobalNetwork_tags(t *testing.T) { }) } -func testAccCheckAwsNetworkManagerGlobalNetworkDestroy(s *terraform.State) error { +func testAccCheckAwsGlobalNetworkDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn for _, rs := range s.RootModule().Resources { @@ -177,7 +177,7 @@ func testAccCheckAwsNetworkManagerGlobalNetworkDestroy(s *terraform.State) error return nil } -func testAccCheckAwsNetworkManagerGlobalNetworkExists(name string) resource.TestCheckFunc { +func testAccCheckAwsGlobalNetworkExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[name] if !ok { @@ -204,7 +204,7 @@ func testAccCheckAwsNetworkManagerGlobalNetworkExists(name string) resource.Test } } -func testAccNetworkManagerGlobalNetworkConfig(description string) string { +func testAccGlobalNetworkConfig(description string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { description = %q @@ -212,7 +212,7 @@ resource "aws_networkmanager_global_network" "test" { `, description) } -func testAccNetworkManagerGlobalNetworkConfigTags1(description, tagKey1, tagValue1 string) string { +func testAccGlobalNetworkConfigTags1(description, tagKey1, tagValue1 string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { description = %q @@ -224,7 +224,7 @@ resource "aws_networkmanager_global_network" "test" { `, description, tagKey1, tagValue1) } -func testAccNetworkManagerGlobalNetworkConfigTags2(description, tagKey1, tagValue1, tagKey2, tagValue2 string) string { +func testAccGlobalNetworkConfigTags2(description, tagKey1, tagValue1, tagKey2, tagValue2 string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { description = %q @@ -237,7 +237,7 @@ resource "aws_networkmanager_global_network" "test" { `, description, tagKey1, tagValue1, tagKey2, tagValue2) } -func testAccNetworkManagerGlobalNetworkConfig_Update(description string) string { +func testAccGlobalNetworkConfig_Update(description string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { description = %q diff --git a/internal/service/networkmanager/site.go b/internal/service/networkmanager/site.go index f6e1bd26593..4bd97ee231b 100644 --- a/internal/service/networkmanager/site.go +++ b/internal/service/networkmanager/site.go @@ -14,12 +14,12 @@ import ( "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) -func resourceAwsNetworkManagerSite() *schema.Resource { +func ResourceSite() *schema.Resource { return &schema.Resource{ - Create: resourceAwsNetworkManagerSiteCreate, - Read: resourceAwsNetworkManagerSiteRead, - Update: resourceAwsNetworkManagerSiteUpdate, - Delete: resourceAwsNetworkManagerSiteDelete, + Create: ResourceSiteCreate, + Read: ResourceSiteRead, + Update: ResourceSiteUpdate, + Delete: ResourceSiteDelete, Importer: &schema.ResourceImporter{ State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { d.Set("arn", d.Id()) @@ -83,7 +83,7 @@ func resourceAwsNetworkManagerSite() *schema.Resource { } } -func resourceAwsNetworkManagerSiteCreate(d *schema.ResourceData, meta interface{}) error { +func ResourceSiteCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn input := &networkmanager.CreateSiteInput{ @@ -114,10 +114,10 @@ func resourceAwsNetworkManagerSiteCreate(d *schema.ResourceData, meta interface{ return fmt.Errorf("error waiting for Network Manager Site (%s) availability: %s", d.Id(), err) } - return resourceAwsNetworkManagerSiteRead(d, meta) + return ResourceSiteRead(d, meta) } -func resourceAwsNetworkManagerSiteRead(d *schema.ResourceData, meta interface{}) error { +func ResourceSiteRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig @@ -159,7 +159,7 @@ func resourceAwsNetworkManagerSiteRead(d *schema.ResourceData, meta interface{}) return nil } -func resourceAwsNetworkManagerSiteUpdate(d *schema.ResourceData, meta interface{}) error { +func ResourceSiteUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn if d.HasChanges("description", "location") { @@ -187,7 +187,7 @@ func resourceAwsNetworkManagerSiteUpdate(d *schema.ResourceData, meta interface{ return nil } -func resourceAwsNetworkManagerSiteDelete(d *schema.ResourceData, meta interface{}) error { +func ResourceSiteDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn input := &networkmanager.DeleteSiteInput{ @@ -226,7 +226,7 @@ func resourceAwsNetworkManagerSiteDelete(d *schema.ResourceData, meta interface{ return fmt.Errorf("error deleting Network Manager Site: %s", err) } - if err := waitForNetworkManagerSiteDeletion(conn, d.Get("global_network_id").(string), d.Id()); err != nil { + if err := waitForSiteDeletion(conn, d.Get("global_network_id").(string), d.Id()); err != nil { return fmt.Errorf("error waiting for Network Manager Site (%s) deletion: %s", d.Id(), err) } @@ -291,7 +291,7 @@ func networkmanagerDescribeSite(conn *networkmanager.NetworkManager, globalNetwo return nil, nil } -func waitForNetworkManagerSiteDeletion(conn *networkmanager.NetworkManager, globalNetworkID, siteID string) error { +func waitForSiteDeletion(conn *networkmanager.NetworkManager, globalNetworkID, siteID string) error { stateConf := &resource.StateChangeConf{ Pending: []string{ networkmanager.SiteStateAvailable, diff --git a/internal/service/networkmanager/site_data_source.go b/internal/service/networkmanager/site_data_source.go index 5adf92456ba..aa1fadf3324 100644 --- a/internal/service/networkmanager/site_data_source.go +++ b/internal/service/networkmanager/site_data_source.go @@ -11,9 +11,9 @@ import ( "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) -func dataSourceAwsNetworkManagerSite() *schema.Resource { +func DataSourceSite() *schema.Resource { return &schema.Resource{ - Read: dataSourceAwsNetworkManagerSiteRead, + Read: DataSourceSiteRead, Schema: map[string]*schema.Schema{ "arn": { @@ -57,7 +57,7 @@ func dataSourceAwsNetworkManagerSite() *schema.Resource { } } -func dataSourceAwsNetworkManagerSiteRead(d *schema.ResourceData, meta interface{}) error { +func DataSourceSiteRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig diff --git a/internal/service/networkmanager/site_data_source_test.go b/internal/service/networkmanager/site_data_source_test.go index cc5e064090f..a6250eb5b94 100644 --- a/internal/service/networkmanager/site_data_source_test.go +++ b/internal/service/networkmanager/site_data_source_test.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) -func TestAccDataSourceAWSNetworkManagerSite_basic(t *testing.T) { +func TestAccDataSourceSite_basic(t *testing.T) { dataSourceName := "data.aws_networkmanager_site.test" dataSourceByIdName := "data.aws_networkmanager_site.test_by_id" dataSourceByTagsName := "data.aws_networkmanager_site.test_by_tags" @@ -20,10 +20,10 @@ func TestAccDataSourceAWSNetworkManagerSite_basic(t *testing.T) { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckAwsNetworkManagerSiteDestroy, + CheckDestroy: testAccCheckAwsSiteDestroy, Steps: []resource.TestStep{ { - Config: testAccDataSourceAwsNetworkManagerSiteConfig(), + Config: testAccDataSourceSiteConfig(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrPair(dataSourceName, "id", resourceName, "id"), resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"), @@ -43,7 +43,7 @@ func TestAccDataSourceAWSNetworkManagerSite_basic(t *testing.T) { }) } -func testAccDataSourceAwsNetworkManagerSiteConfig() string { +func testAccDataSourceSiteConfig() string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { description = "test" diff --git a/internal/service/networkmanager/site_test.go b/internal/service/networkmanager/site_test.go index 99ce64272bd..257087e50af 100644 --- a/internal/service/networkmanager/site_test.go +++ b/internal/service/networkmanager/site_test.go @@ -15,11 +15,11 @@ import ( func init() { resource.AddTestSweepers("aws_networkmanager_site", &resource.Sweeper{ Name: "aws_networkmanager_site", - F: testSweepNetworkManagerSite, + F: testSweepSite, }) } -func testSweepNetworkManagerSite(region string) error { +func testSweepSite(region string) error { client, err := sharedClientForRegion(region) if err != nil { return fmt.Errorf("error getting client: %s", err) @@ -51,7 +51,7 @@ func testSweepNetworkManagerSite(region string) error { continue } - if err := waitForNetworkManagerSiteDeletion(conn, globalNetworkID, id); err != nil { + if err := waitForSiteDeletion(conn, globalNetworkID, id); err != nil { sweeperErr := fmt.Errorf("error waiting for Network Manager Site (%s) deletion: %s", id, err) log.Printf("[ERROR] %s", sweeperErr) sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) @@ -72,19 +72,19 @@ func testSweepNetworkManagerSite(region string) error { return sweeperErrs.ErrorOrNil() } -func TestAccAWSNetworkManagerSite_basic(t *testing.T) { +func TestAccSite_basic(t *testing.T) { resourceName := "aws_networkmanager_site.test" gloablNetworkResourceName := "aws_networkmanager_global_network.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckAwsNetworkManagerSiteDestroy, + CheckDestroy: testAccCheckAwsSiteDestroy, Steps: []resource.TestStep{ { - Config: testAccNetworkManagerSiteConfig("test"), + Config: testAccSiteConfig("test"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerSiteExists(resourceName), + testAccCheckAwsSiteExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "arn"), resource.TestCheckResourceAttr(resourceName, "description", "test"), resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetworkResourceName, "id"), @@ -94,13 +94,13 @@ func TestAccAWSNetworkManagerSite_basic(t *testing.T) { { ResourceName: resourceName, ImportState: true, - ImportStateIdFunc: testAccAWSNetworkManagerSiteImportStateIdFunc(resourceName), + ImportStateIdFunc: testAccSiteImportStateIdFunc(resourceName), ImportStateVerify: true, }, { - Config: testAccNetworkManagerSiteConfig_Update("test updated", "18.0029784", "-76.7897987"), + Config: testAccSiteConfig_Update("test updated", "18.0029784", "-76.7897987"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerSiteExists(resourceName), + testAccCheckAwsSiteExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "arn"), resource.TestCheckResourceAttr(resourceName, "description", "test updated"), resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetworkResourceName, "id"), @@ -114,19 +114,19 @@ func TestAccAWSNetworkManagerSite_basic(t *testing.T) { }) } -func TestAccAWSNetworkManagerSite_tags(t *testing.T) { +func TestAccSite_tags(t *testing.T) { resourceName := "aws_networkmanager_site.test" description := "test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckAwsNetworkManagerSiteDestroy, + CheckDestroy: testAccCheckAwsSiteDestroy, Steps: []resource.TestStep{ { - Config: testAccNetworkManagerSiteConfigTags1(description, "key1", "value1"), + Config: testAccSiteConfigTags1(description, "key1", "value1"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerSiteExists(resourceName), + testAccCheckAwsSiteExists(resourceName), resource.TestCheckResourceAttr(resourceName, "description", "test"), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), @@ -135,13 +135,13 @@ func TestAccAWSNetworkManagerSite_tags(t *testing.T) { { ResourceName: resourceName, ImportState: true, - ImportStateIdFunc: testAccAWSNetworkManagerSiteImportStateIdFunc(resourceName), + ImportStateIdFunc: testAccSiteImportStateIdFunc(resourceName), ImportStateVerify: true, }, { - Config: testAccNetworkManagerSiteConfigTags2(description, "key1", "value1updated", "key2", "value2"), + Config: testAccSiteConfigTags2(description, "key1", "value1updated", "key2", "value2"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerSiteExists(resourceName), + testAccCheckAwsSiteExists(resourceName), resource.TestCheckResourceAttr(resourceName, "description", "test"), resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), @@ -149,9 +149,9 @@ func TestAccAWSNetworkManagerSite_tags(t *testing.T) { ), }, { - Config: testAccNetworkManagerSiteConfigTags1(description, "key2", "value2"), + Config: testAccSiteConfigTags1(description, "key2", "value2"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerSiteExists(resourceName), + testAccCheckAwsSiteExists(resourceName), resource.TestCheckResourceAttr(resourceName, "description", "test"), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), @@ -161,7 +161,7 @@ func TestAccAWSNetworkManagerSite_tags(t *testing.T) { }) } -func testAccCheckAwsNetworkManagerSiteDestroy(s *terraform.State) error { +func testAccCheckAwsSiteDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn for _, rs := range s.RootModule().Resources { @@ -187,7 +187,7 @@ func testAccCheckAwsNetworkManagerSiteDestroy(s *terraform.State) error { return nil } -func testAccCheckAwsNetworkManagerSiteExists(name string) resource.TestCheckFunc { +func testAccCheckAwsSiteExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[name] if !ok { @@ -214,7 +214,7 @@ func testAccCheckAwsNetworkManagerSiteExists(name string) resource.TestCheckFunc } } -func testAccNetworkManagerSiteConfig(description string) string { +func testAccSiteConfig(description string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { description = "test" @@ -227,7 +227,7 @@ resource "aws_networkmanager_site" "test" { `, description) } -func testAccNetworkManagerSiteConfigTags1(description, tagKey1, tagValue1 string) string { +func testAccSiteConfigTags1(description, tagKey1, tagValue1 string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { description = "test" @@ -244,7 +244,7 @@ resource "aws_networkmanager_site" "test" { `, description, tagKey1, tagValue1) } -func testAccNetworkManagerSiteConfigTags2(description, tagKey1, tagValue1, tagKey2, tagValue2 string) string { +func testAccSiteConfigTags2(description, tagKey1, tagValue1, tagKey2, tagValue2 string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { description = "test" @@ -262,7 +262,7 @@ resource "aws_networkmanager_site" "test" { `, description, tagKey1, tagValue1, tagKey2, tagValue2) } -func testAccNetworkManagerSiteConfig_Update(description, latitude, longitude string) string { +func testAccSiteConfig_Update(description, latitude, longitude string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { description = "test" @@ -280,7 +280,7 @@ resource "aws_networkmanager_site" "test" { `, description, latitude, longitude) } -func testAccAWSNetworkManagerSiteImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { +func testAccSiteImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { return func(s *terraform.State) (string, error) { rs, ok := s.RootModule().Resources[resourceName] if !ok { diff --git a/internal/service/networkmanager/transit_gateway_registration.go b/internal/service/networkmanager/transit_gateway_registration.go index d535a23717e..d77208348e8 100644 --- a/internal/service/networkmanager/transit_gateway_registration.go +++ b/internal/service/networkmanager/transit_gateway_registration.go @@ -13,11 +13,11 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func resourceAwsNetworkManagerTransitGatewayRegistration() *schema.Resource { +func ResourceTransitGatewayRegistration() *schema.Resource { return &schema.Resource{ - Create: resourceAwsNetworkManagerTransitGatewayRegistrationCreate, - Read: resourceAwsNetworkManagerTransitGatewayRegistrationRead, - Delete: resourceAwsNetworkManagerTransitGatewayRegistrationDelete, + Create: ResourceTransitGatewayRegistrationCreate, + Read: ResourceTransitGatewayRegistrationRead, + Delete: ResourceTransitGatewayRegistrationDelete, Importer: &schema.ResourceImporter{ State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { idErr := fmt.Errorf("Expected ID in format of arn:aws:ec2:REGION:ACCOUNTID:transit-gateway/TGWID,GLOBALNETWORKID and provided: %s", d.Id()) @@ -53,7 +53,7 @@ func resourceAwsNetworkManagerTransitGatewayRegistration() *schema.Resource { } } -func resourceAwsNetworkManagerTransitGatewayRegistrationCreate(d *schema.ResourceData, meta interface{}) error { +func ResourceTransitGatewayRegistrationCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn globalNetworkId := d.Get("global_network_id").(string) @@ -85,10 +85,10 @@ func resourceAwsNetworkManagerTransitGatewayRegistrationCreate(d *schema.Resourc return fmt.Errorf("error waiting for Network Manager Transit Gateway Registration (%s) availability: %s", d.Id(), err) } - return resourceAwsNetworkManagerTransitGatewayRegistrationRead(d, meta) + return ResourceTransitGatewayRegistrationRead(d, meta) } -func resourceAwsNetworkManagerTransitGatewayRegistrationRead(d *schema.ResourceData, meta interface{}) error { +func ResourceTransitGatewayRegistrationRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn transitGatewayRegistration, err := networkmanagerDescribeTransitGatewayRegistration(conn, d.Get("global_network_id").(string), d.Get("transit_gateway_arn").(string)) @@ -118,7 +118,7 @@ func resourceAwsNetworkManagerTransitGatewayRegistrationRead(d *schema.ResourceD return nil } -func resourceAwsNetworkManagerTransitGatewayRegistrationDelete(d *schema.ResourceData, meta interface{}) error { +func ResourceTransitGatewayRegistrationDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).networkmanagerconn input := &networkmanager.DeregisterTransitGatewayInput{ @@ -138,7 +138,7 @@ func resourceAwsNetworkManagerTransitGatewayRegistrationDelete(d *schema.Resourc return fmt.Errorf("error deleting Network Manager Transit Gateway Registration: %s", err) } - if err := waitForNetworkManagerTransitGatewayRegistrationDeletion(conn, d.Get("global_network_id").(string), d.Get("transit_gateway_arn").(string)); err != nil { + if err := waitForTransitGatewayRegistrationDeletion(conn, d.Get("global_network_id").(string), d.Get("transit_gateway_arn").(string)); err != nil { return fmt.Errorf("error waiting for Network Manager Transit Gateway Registration (%s) deletion: %s", d.Id(), err) } @@ -203,7 +203,7 @@ func networkmanagerDescribeTransitGatewayRegistration(conn *networkmanager.Netwo return nil, nil } -func waitForNetworkManagerTransitGatewayRegistrationDeletion(conn *networkmanager.NetworkManager, globalNetworkID, transitGatewayArn string) error { +func waitForTransitGatewayRegistrationDeletion(conn *networkmanager.NetworkManager, globalNetworkID, transitGatewayArn string) error { stateConf := &resource.StateChangeConf{ Pending: []string{ networkmanager.TransitGatewayRegistrationStateAvailable, diff --git a/internal/service/networkmanager/transit_gateway_registration_test.go b/internal/service/networkmanager/transit_gateway_registration_test.go index afc2a55dd74..32940d58228 100644 --- a/internal/service/networkmanager/transit_gateway_registration_test.go +++ b/internal/service/networkmanager/transit_gateway_registration_test.go @@ -15,10 +15,10 @@ import ( func init() { resource.AddTestSweepers("aws_networkmanager_transit_gateway_registration", &resource.Sweeper{ Name: "aws_networkmanager_transit_gateway_registration", - F: testSweepNetworkManagerTransitGatewayRegistration, + F: testSweepTransitGatewayRegistration, }) } -func testSweepNetworkManagerTransitGatewayRegistration(region string) error { +func testSweepTransitGatewayRegistration(region string) error { client, err := sharedClientForRegion(region) if err != nil { return fmt.Errorf("error getting client: %s", err) @@ -46,7 +46,7 @@ func testSweepNetworkManagerTransitGatewayRegistration(region string) error { sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) continue } - if err := waitForNetworkManagerTransitGatewayRegistrationDeletion(conn, globalNetworkID, transitGatewayArn); err != nil { + if err := waitForTransitGatewayRegistrationDeletion(conn, globalNetworkID, transitGatewayArn); err != nil { sweeperErr := fmt.Errorf("error waiting for Network Manager Transit Gateway Registration (%s) deletion: %s", transitGatewayArn, err) log.Printf("[ERROR] %s", sweeperErr) sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) @@ -64,7 +64,7 @@ func testSweepNetworkManagerTransitGatewayRegistration(region string) error { } return sweeperErrs.ErrorOrNil() } -func TestAccAWSNetworkManagerTransitGatewayRegistration_basic(t *testing.T) { +func TestAccTransitGatewayRegistration_basic(t *testing.T) { resourceName := "aws_networkmanager_transit_gateway_registration.test" gloablNetworkResourceName := "aws_networkmanager_global_network.test" gloablNetwork2ResourceName := "aws_networkmanager_global_network.test2" @@ -72,12 +72,12 @@ func TestAccAWSNetworkManagerTransitGatewayRegistration_basic(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSEc2TransitGateway(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckAwsNetworkManagerTransitGatewayRegistrationDestroy, + CheckDestroy: testAccCheckAwsTransitGatewayRegistrationDestroy, Steps: []resource.TestStep{ { - Config: testAccNetworkManagerTransitGatewayRegistrationConfig(), + Config: testAccTransitGatewayRegistrationConfig(), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerTransitGatewayRegistrationExists(resourceName), + testAccCheckAwsTransitGatewayRegistrationExists(resourceName), resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetworkResourceName, "id"), resource.TestCheckResourceAttrPair(resourceName, "transit_gateway_arn", transitGatewayResourceName, "arn"), ), @@ -85,13 +85,13 @@ func TestAccAWSNetworkManagerTransitGatewayRegistration_basic(t *testing.T) { { ResourceName: resourceName, ImportState: true, - ImportStateIdFunc: testAccAWSNetworkManagerTransitGatewayRegistrationImportStateIdFunc(resourceName), + ImportStateIdFunc: testAccTransitGatewayRegistrationImportStateIdFunc(resourceName), ImportStateVerify: true, }, { - Config: testAccNetworkManagerTransitGatewayRegistrationConfig_Update(), + Config: testAccTransitGatewayRegistrationConfig_Update(), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsNetworkManagerTransitGatewayRegistrationExists(resourceName), + testAccCheckAwsTransitGatewayRegistrationExists(resourceName), resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetwork2ResourceName, "id"), resource.TestCheckResourceAttrPair(resourceName, "transit_gateway_arn", transitGatewayResourceName, "arn"), ), @@ -99,7 +99,7 @@ func TestAccAWSNetworkManagerTransitGatewayRegistration_basic(t *testing.T) { }, }) } -func testAccCheckAwsNetworkManagerTransitGatewayRegistrationDestroy(s *terraform.State) error { +func testAccCheckAwsTransitGatewayRegistrationDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_networkmanager_transit_gateway_registration" { @@ -119,7 +119,7 @@ func testAccCheckAwsNetworkManagerTransitGatewayRegistrationDestroy(s *terraform } return nil } -func testAccCheckAwsNetworkManagerTransitGatewayRegistrationExists(name string) resource.TestCheckFunc { +func testAccCheckAwsTransitGatewayRegistrationExists(name string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[name] if !ok { @@ -139,7 +139,7 @@ func testAccCheckAwsNetworkManagerTransitGatewayRegistrationExists(name string) return err } } -func testAccNetworkManagerTransitGatewayRegistrationConfig() string { +func testAccTransitGatewayRegistrationConfig() string { return ` resource "aws_networkmanager_global_network" "test" { description = "test" @@ -151,7 +151,7 @@ resource "aws_networkmanager_transit_gateway_registration" "test" { } ` } -func testAccNetworkManagerTransitGatewayRegistrationConfig_Update() string { +func testAccTransitGatewayRegistrationConfig_Update() string { return ` resource "aws_networkmanager_global_network" "test" { description = "test" @@ -166,7 +166,7 @@ resource "aws_networkmanager_transit_gateway_registration" "test" { } ` } -func testAccAWSNetworkManagerTransitGatewayRegistrationImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { +func testAccTransitGatewayRegistrationImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { return func(s *terraform.State) (string, error) { rs, ok := s.RootModule().Resources[resourceName] if !ok { From c452550a7cfc98eac682d1be9ef4faf8f143cac3 Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Mon, 6 Dec 2021 22:41:56 +0000 Subject: [PATCH 032/229] networkmanager: change go package --- internal/service/networkmanager/device.go | 2 +- internal/service/networkmanager/device_data_source.go | 2 +- internal/service/networkmanager/device_data_source_test.go | 2 +- internal/service/networkmanager/device_test.go | 2 +- internal/service/networkmanager/global_network.go | 2 +- internal/service/networkmanager/global_network_data_source.go | 2 +- .../service/networkmanager/global_network_data_source_test.go | 2 +- internal/service/networkmanager/global_network_test.go | 2 +- internal/service/networkmanager/site.go | 2 +- internal/service/networkmanager/site_data_source.go | 2 +- internal/service/networkmanager/site_data_source_test.go | 2 +- internal/service/networkmanager/site_test.go | 2 +- internal/service/networkmanager/transit_gateway_registration.go | 2 +- .../service/networkmanager/transit_gateway_registration_test.go | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/internal/service/networkmanager/device.go b/internal/service/networkmanager/device.go index 6a0ddc68b8a..ad8dd5b1641 100644 --- a/internal/service/networkmanager/device.go +++ b/internal/service/networkmanager/device.go @@ -1,4 +1,4 @@ -package aws +package networkmanager import ( "fmt" diff --git a/internal/service/networkmanager/device_data_source.go b/internal/service/networkmanager/device_data_source.go index c1128addec8..554d9e8518f 100644 --- a/internal/service/networkmanager/device_data_source.go +++ b/internal/service/networkmanager/device_data_source.go @@ -1,4 +1,4 @@ -package aws +package networkmanager import ( "errors" diff --git a/internal/service/networkmanager/device_data_source_test.go b/internal/service/networkmanager/device_data_source_test.go index 7d93d94ea1d..d7b12812284 100644 --- a/internal/service/networkmanager/device_data_source_test.go +++ b/internal/service/networkmanager/device_data_source_test.go @@ -1,4 +1,4 @@ -package aws +package networkmanager import ( "fmt" diff --git a/internal/service/networkmanager/device_test.go b/internal/service/networkmanager/device_test.go index a127315688c..778f5164f09 100644 --- a/internal/service/networkmanager/device_test.go +++ b/internal/service/networkmanager/device_test.go @@ -1,4 +1,4 @@ -package aws +package networkmanager import ( "fmt" diff --git a/internal/service/networkmanager/global_network.go b/internal/service/networkmanager/global_network.go index ffc207ef40c..da6c91cbf2b 100644 --- a/internal/service/networkmanager/global_network.go +++ b/internal/service/networkmanager/global_network.go @@ -1,4 +1,4 @@ -package aws +package networkmanager import ( "fmt" diff --git a/internal/service/networkmanager/global_network_data_source.go b/internal/service/networkmanager/global_network_data_source.go index f0b8eb9275f..0fcdbc40602 100644 --- a/internal/service/networkmanager/global_network_data_source.go +++ b/internal/service/networkmanager/global_network_data_source.go @@ -1,4 +1,4 @@ -package aws +package networkmanager import ( "errors" diff --git a/internal/service/networkmanager/global_network_data_source_test.go b/internal/service/networkmanager/global_network_data_source_test.go index c4988a4a1d8..7ecb6495d49 100644 --- a/internal/service/networkmanager/global_network_data_source_test.go +++ b/internal/service/networkmanager/global_network_data_source_test.go @@ -1,4 +1,4 @@ -package aws +package networkmanager import ( "fmt" diff --git a/internal/service/networkmanager/global_network_test.go b/internal/service/networkmanager/global_network_test.go index 7b51e423f58..e3b29a1ae2d 100644 --- a/internal/service/networkmanager/global_network_test.go +++ b/internal/service/networkmanager/global_network_test.go @@ -1,4 +1,4 @@ -package aws +package networkmanager import ( "fmt" diff --git a/internal/service/networkmanager/site.go b/internal/service/networkmanager/site.go index 4bd97ee231b..9a8742b756e 100644 --- a/internal/service/networkmanager/site.go +++ b/internal/service/networkmanager/site.go @@ -1,4 +1,4 @@ -package aws +package networkmanager import ( "fmt" diff --git a/internal/service/networkmanager/site_data_source.go b/internal/service/networkmanager/site_data_source.go index aa1fadf3324..14063f66980 100644 --- a/internal/service/networkmanager/site_data_source.go +++ b/internal/service/networkmanager/site_data_source.go @@ -1,4 +1,4 @@ -package aws +package networkmanager import ( "errors" diff --git a/internal/service/networkmanager/site_data_source_test.go b/internal/service/networkmanager/site_data_source_test.go index a6250eb5b94..7e21dd4df0a 100644 --- a/internal/service/networkmanager/site_data_source_test.go +++ b/internal/service/networkmanager/site_data_source_test.go @@ -1,4 +1,4 @@ -package aws +package networkmanager import ( "fmt" diff --git a/internal/service/networkmanager/site_test.go b/internal/service/networkmanager/site_test.go index 257087e50af..4438d8bfa2f 100644 --- a/internal/service/networkmanager/site_test.go +++ b/internal/service/networkmanager/site_test.go @@ -1,4 +1,4 @@ -package aws +package networkmanager import ( "fmt" diff --git a/internal/service/networkmanager/transit_gateway_registration.go b/internal/service/networkmanager/transit_gateway_registration.go index d77208348e8..97ea4f09eae 100644 --- a/internal/service/networkmanager/transit_gateway_registration.go +++ b/internal/service/networkmanager/transit_gateway_registration.go @@ -1,4 +1,4 @@ -package aws +package networkmanager import ( "fmt" diff --git a/internal/service/networkmanager/transit_gateway_registration_test.go b/internal/service/networkmanager/transit_gateway_registration_test.go index 32940d58228..c93ec058cc9 100644 --- a/internal/service/networkmanager/transit_gateway_registration_test.go +++ b/internal/service/networkmanager/transit_gateway_registration_test.go @@ -1,4 +1,4 @@ -package aws +package networkmanager import ( "fmt" From eef85aed0017d56f2c16df9a9c28de34c96b575a Mon Sep 17 00:00:00 2001 From: Omarimcblack Date: Mon, 6 Dec 2021 23:28:08 +0000 Subject: [PATCH 033/229] networkmanager: ensure correct internal funcs use --- internal/service/networkmanager/device.go | 18 ++++++------ .../networkmanager/device_data_source_test.go | 9 +++--- .../service/networkmanager/device_test.go | 10 ++++--- .../service/networkmanager/global_network.go | 28 ++++++++++--------- .../global_network_data_source_test.go | 9 +++--- .../networkmanager/global_network_test.go | 10 ++++--- internal/service/networkmanager/site.go | 18 ++++++------ .../networkmanager/site_data_source_test.go | 9 +++--- internal/service/networkmanager/site_test.go | 10 ++++--- .../transit_gateway_registration.go | 10 ++++--- .../transit_gateway_registration_test.go | 9 ++++-- 11 files changed, 80 insertions(+), 60 deletions(-) diff --git a/internal/service/networkmanager/device.go b/internal/service/networkmanager/device.go index ad8dd5b1641..0c27c72c7cc 100644 --- a/internal/service/networkmanager/device.go +++ b/internal/service/networkmanager/device.go @@ -9,9 +9,11 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" + "github.com/terraform-providers/terraform-provider-aws/internal/keyvaluetags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) func ResourceDevice() *schema.Resource { @@ -148,7 +150,7 @@ func ResourceDeviceRead(d *schema.ResourceData, meta interface{}) error { device, err := networkmanagerDescribeDevice(conn, d.Get("global_network_id").(string), d.Id()) - if isAWSErr(err, "InvalidDeviceID.NotFound", "") { + if tfawserr.ErrCodeEquals(err, "InvalidDeviceID.NotFound", "") { log.Printf("[WARN] Network Manager Device (%s) not found, removing from state", d.Id()) d.SetId("") return nil @@ -234,11 +236,11 @@ func ResourceDeviceDelete(d *schema.ResourceData, meta interface{}) error { err := resource.Retry(2*time.Minute, func() *resource.RetryError { _, err := conn.DeleteDevice(input) - if isAWSErr(err, "IncorrectState", "has non-deleted Device Associations") { + if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Device Associations") { return resource.RetryableError(err) } - if isAWSErr(err, "IncorrectState", "has non-deleted Device") { + if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Device") { return resource.RetryableError(err) } @@ -249,11 +251,11 @@ func ResourceDeviceDelete(d *schema.ResourceData, meta interface{}) error { return nil }) - if isResourceTimeoutError(err) { + if tfresource.TimedOut(err) { _, err = conn.DeleteDevice(input) } - if isAWSErr(err, "InvalidDeviceID.NotFound", "") { + if tfawserr.ErrCodeEquals(err, "InvalidDeviceID.NotFound", "") { return nil } @@ -272,7 +274,7 @@ func networkmanagerDeviceRefreshFunc(conn *networkmanager.NetworkManager, global return func() (interface{}, string, error) { device, err := networkmanagerDescribeDevice(conn, globalNetworkID, deviceID) - if isAWSErr(err, "InvalidDeviceID.NotFound", "") { + if tfawserr.ErrCodeEquals(err, "InvalidDeviceID.NotFound", "") { return nil, "DELETED", nil } @@ -341,7 +343,7 @@ func waitForNetworkManagerDeviceDeletion(conn *networkmanager.NetworkManager, gl log.Printf("[DEBUG] Waiting for Network Manager Device (%s) deletion", deviceID) _, err := stateConf.WaitForState() - if isResourceNotFoundError(err) { + if tfresource.NotFound(err) { return nil } diff --git a/internal/service/networkmanager/device_data_source_test.go b/internal/service/networkmanager/device_data_source_test.go index d7b12812284..0ec9c44544d 100644 --- a/internal/service/networkmanager/device_data_source_test.go +++ b/internal/service/networkmanager/device_data_source_test.go @@ -1,11 +1,12 @@ -package networkmanager +package networkmanager_test import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" ) func TestAccDataSourceDevice_basic(t *testing.T) { @@ -19,7 +20,7 @@ func TestAccDataSourceDevice_basic(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { - testAccPreCheck(t) + acctest.PreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAwsDeviceDestroy, @@ -104,5 +105,5 @@ data "aws_networkmanager_device" "test_by_tags" { Name = aws_networkmanager_device.test.tags["Name"] } } -`, acctest.RandInt()) +`, sdkacctest.RandInt()) } diff --git a/internal/service/networkmanager/device_test.go b/internal/service/networkmanager/device_test.go index 778f5164f09..180b033acf2 100644 --- a/internal/service/networkmanager/device_test.go +++ b/internal/service/networkmanager/device_test.go @@ -7,9 +7,11 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" ) func init() { @@ -40,7 +42,7 @@ func testSweepDevice(region string) error { log.Printf("[INFO] Deleting Network Manager Device: %s", id) _, err := conn.DeleteDevice(input) - if isAWSErr(err, "InvalidDeviceID.NotFound", "") { + if tfawserr.ErrCodeEquals(err, "InvalidDeviceID.NotFound", "") { continue } @@ -79,7 +81,7 @@ func TestAccDevice_basic(t *testing.T) { gloablNetworkResourceName := "aws_networkmanager_global_network.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, + PreCheck: func() { acctest.PreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAwsDeviceDestroy, Steps: []resource.TestStep{ @@ -131,7 +133,7 @@ func TestAccDevice_tags(t *testing.T) { description := "test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, + PreCheck: func() { acctest.PreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAwsDeviceDestroy, Steps: []resource.TestStep{ @@ -183,7 +185,7 @@ func testAccCheckAwsDeviceDestroy(s *terraform.State) error { device, err := networkmanagerDescribeDevice(conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) if err != nil { - if isAWSErr(err, networkmanager.ErrCodeValidationException, "") { + if tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeValidationException, "") { return nil } return err diff --git a/internal/service/networkmanager/global_network.go b/internal/service/networkmanager/global_network.go index da6c91cbf2b..6bce3707855 100644 --- a/internal/service/networkmanager/global_network.go +++ b/internal/service/networkmanager/global_network.go @@ -7,9 +7,11 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" + "github.com/terraform-providers/terraform-provider-aws/internal/keyvaluetags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) func ResourceGlobalNetwork() *schema.Resource { @@ -54,14 +56,14 @@ func ResourceGlobalNetworkCreate(d *schema.ResourceData, meta interface{}) error var err error output, err = conn.CreateGlobalNetwork(input) if err != nil { - if isAWSErr(err, "ValidationException", "Resource already exists with ID") { + if tfawserr.ErrMessageContains(err, "ValidationException", "Resource already exists with ID") { return resource.RetryableError(err) } return resource.NonRetryableError(err) } return nil }) - if isResourceTimeoutError(err) { + if tfresource.TimedOut(err) { output, err = conn.CreateGlobalNetwork(input) } if err != nil { @@ -91,7 +93,7 @@ func ResourceGlobalNetworkRead(d *schema.ResourceData, meta interface{}) error { globalNetwork, err := networkmanagerDescribeGlobalNetwork(conn, d.Id()) - if isAWSErr(err, "InvalidGlobalNetworkID.NotFound", "") { + if tfawserr.ErrCodeEquals(err, "InvalidGlobalNetworkID.NotFound", "") { log.Printf("[WARN] networkmanager Global Network (%s) not found, removing from state", d.Id()) d.SetId("") return nil @@ -160,23 +162,23 @@ func ResourceGlobalNetworkDelete(d *schema.ResourceData, meta interface{}) error err := resource.Retry(2*time.Minute, func() *resource.RetryError { _, err := conn.DeleteGlobalNetwork(input) - if isAWSErr(err, "IncorrectState", "has non-deleted Transit Gateway Registrations") { + if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Transit Gateway Registrations") { return resource.RetryableError(err) } - if isAWSErr(err, "IncorrectState", "has non-deleted Customer Gateway Associations") { + if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Customer Gateway Associations") { return resource.RetryableError(err) } - if isAWSErr(err, "IncorrectState", "has non-deleted Device") { + if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Device") { return resource.RetryableError(err) } - if isAWSErr(err, "IncorrectState", "has non-deleted Link") { + if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Link") { return resource.RetryableError(err) } - if isAWSErr(err, "IncorrectState", "has non-deleted Site") { + if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Site") { return resource.RetryableError(err) } @@ -187,11 +189,11 @@ func ResourceGlobalNetworkDelete(d *schema.ResourceData, meta interface{}) error return nil }) - if isResourceTimeoutError(err) { + if tfresource.TimedOut(err) { _, err = conn.DeleteGlobalNetwork(input) } - if isAWSErr(err, "InvalidGlobalNetworkID.NotFound", "") { + if tfawserr.ErrCodeEquals(err, "InvalidGlobalNetworkID.NotFound", "") { return nil } @@ -210,7 +212,7 @@ func networkmanagerGlobalNetworkRefreshFunc(conn *networkmanager.NetworkManager, return func() (interface{}, string, error) { globalNetwork, err := networkmanagerDescribeGlobalNetwork(conn, globalNetworkID) - if isAWSErr(err, "InvalidGlobalNetworkID.NotFound", "") { + if tfawserr.ErrCodeEquals(err, "InvalidGlobalNetworkID.NotFound", "") { return nil, "DELETED", nil } @@ -278,7 +280,7 @@ func waitForGlobalNetworkDeletion(conn *networkmanager.NetworkManager, globalNet log.Printf("[DEBUG] Waiting for Global Network (%s) deletion", globalNetworkID) _, err := stateConf.WaitForState() - if isResourceNotFoundError(err) { + if tfresource.NotFound(err) { return nil } diff --git a/internal/service/networkmanager/global_network_data_source_test.go b/internal/service/networkmanager/global_network_data_source_test.go index 7ecb6495d49..b71031f9718 100644 --- a/internal/service/networkmanager/global_network_data_source_test.go +++ b/internal/service/networkmanager/global_network_data_source_test.go @@ -1,11 +1,12 @@ -package networkmanager +package networkmanager_test import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" ) func TestAccDataSourceGlobalNetwork_basic(t *testing.T) { @@ -15,7 +16,7 @@ func TestAccDataSourceGlobalNetwork_basic(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { - testAccPreCheck(t) + acctest.PreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAwsGlobalNetworkDestroy, @@ -66,5 +67,5 @@ data "aws_networkmanager_global_network" "test_by_tags" { Name = aws_networkmanager_global_network.test.tags["Name"] } } -`, acctest.RandInt()) +`, sdkacctest.RandInt()) } diff --git a/internal/service/networkmanager/global_network_test.go b/internal/service/networkmanager/global_network_test.go index e3b29a1ae2d..463cc2c2509 100644 --- a/internal/service/networkmanager/global_network_test.go +++ b/internal/service/networkmanager/global_network_test.go @@ -8,9 +8,11 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" ) func init() { @@ -40,7 +42,7 @@ func testSweepGlobalNetwork(region string) error { log.Printf("[INFO] Deleting Network Manager Global Network: %s", id) _, err := conn.DeleteGlobalNetwork(input) - if isAWSErr(err, "InvalidGlobalNetworkID.NotFound", "") { + if tfawserr.ErrCodeEquals(err, "InvalidGlobalNetworkID.NotFound", "") { continue } @@ -76,7 +78,7 @@ func TestAccGlobalNetwork_basic(t *testing.T) { resourceName := "aws_networkmanager_global_network.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, + PreCheck: func() { acctest.PreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAwsGlobalNetworkDestroy, Steps: []resource.TestStep{ @@ -110,7 +112,7 @@ func TestAccGlobalNetwork_tags(t *testing.T) { description := "test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, + PreCheck: func() { acctest.PreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAwsGlobalNetworkDestroy, Steps: []resource.TestStep{ @@ -161,7 +163,7 @@ func testAccCheckAwsGlobalNetworkDestroy(s *terraform.State) error { globalNetwork, err := networkmanagerDescribeGlobalNetwork(conn, rs.Primary.ID) if err != nil { - if isAWSErr(err, networkmanager.ErrCodeResourceNotFoundException, "") { + if tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeResourceNotFoundException, "") { return nil } return err diff --git a/internal/service/networkmanager/site.go b/internal/service/networkmanager/site.go index 9a8742b756e..dc41f5ee148 100644 --- a/internal/service/networkmanager/site.go +++ b/internal/service/networkmanager/site.go @@ -9,9 +9,11 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" + "github.com/terraform-providers/terraform-provider-aws/internal/keyvaluetags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) func ResourceSite() *schema.Resource { @@ -123,7 +125,7 @@ func ResourceSiteRead(d *schema.ResourceData, meta interface{}) error { site, err := networkmanagerDescribeSite(conn, d.Get("global_network_id").(string), d.Id()) - if isAWSErr(err, "InvalidSiteID.NotFound", "") { + if tfawserr.ErrCodeEquals(err, "InvalidSiteID.NotFound", "") { log.Printf("[WARN] Network Manager Site (%s) not found, removing from state", d.Id()) d.SetId("") return nil @@ -199,11 +201,11 @@ func ResourceSiteDelete(d *schema.ResourceData, meta interface{}) error { err := resource.Retry(2*time.Minute, func() *resource.RetryError { _, err := conn.DeleteSite(input) - if isAWSErr(err, "IncorrectState", "has non-deleted Link Associations") { + if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Link Associations") { return resource.RetryableError(err) } - if isAWSErr(err, "IncorrectState", "has non-deleted Device") { + if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Device") { return resource.RetryableError(err) } @@ -214,11 +216,11 @@ func ResourceSiteDelete(d *schema.ResourceData, meta interface{}) error { return nil }) - if isResourceTimeoutError(err) { + if tfresource.TimedOut(err) { _, err = conn.DeleteSite(input) } - if isAWSErr(err, "InvalidSiteID.NotFound", "") { + if tfawserr.ErrCodeEquals(err, "InvalidSiteID.NotFound", "") { return nil } @@ -237,7 +239,7 @@ func networkmanagerSiteRefreshFunc(conn *networkmanager.NetworkManager, globalNe return func() (interface{}, string, error) { site, err := networkmanagerDescribeSite(conn, globalNetworkID, siteID) - if isAWSErr(err, "InvalidSiteID.NotFound", "") { + if tfawserr.ErrCodeEquals(err, "InvalidSiteID.NotFound", "") { return nil, "DELETED", nil } @@ -306,7 +308,7 @@ func waitForSiteDeletion(conn *networkmanager.NetworkManager, globalNetworkID, s log.Printf("[DEBUG] Waiting for Network Manager Site (%s) deletion", siteID) _, err := stateConf.WaitForState() - if isResourceNotFoundError(err) { + if tfresource.NotFound(err) { return nil } diff --git a/internal/service/networkmanager/site_data_source_test.go b/internal/service/networkmanager/site_data_source_test.go index 7e21dd4df0a..9e262e29b29 100644 --- a/internal/service/networkmanager/site_data_source_test.go +++ b/internal/service/networkmanager/site_data_source_test.go @@ -1,11 +1,12 @@ -package networkmanager +package networkmanager_test import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" ) func TestAccDataSourceSite_basic(t *testing.T) { @@ -17,7 +18,7 @@ func TestAccDataSourceSite_basic(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { - testAccPreCheck(t) + acctest.PreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAwsSiteDestroy, @@ -80,5 +81,5 @@ data "aws_networkmanager_site" "test_by_tags" { Name = aws_networkmanager_site.test.tags["Name"] } } -`, acctest.RandInt()) +`, sdkacctest.RandInt()) } diff --git a/internal/service/networkmanager/site_test.go b/internal/service/networkmanager/site_test.go index 4438d8bfa2f..44e94c5c8dd 100644 --- a/internal/service/networkmanager/site_test.go +++ b/internal/service/networkmanager/site_test.go @@ -7,9 +7,11 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" ) func init() { @@ -40,7 +42,7 @@ func testSweepSite(region string) error { log.Printf("[INFO] Deleting Network Manager Site: %s", id) _, err := conn.DeleteSite(input) - if isAWSErr(err, "InvalidSiteID.NotFound", "") { + if tfawserr.ErrCodeEquals(err, "InvalidSiteID.NotFound", "") { continue } @@ -77,7 +79,7 @@ func TestAccSite_basic(t *testing.T) { gloablNetworkResourceName := "aws_networkmanager_global_network.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, + PreCheck: func() { acctest.PreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAwsSiteDestroy, Steps: []resource.TestStep{ @@ -119,7 +121,7 @@ func TestAccSite_tags(t *testing.T) { description := "test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, + PreCheck: func() { acctest.PreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAwsSiteDestroy, Steps: []resource.TestStep{ @@ -171,7 +173,7 @@ func testAccCheckAwsSiteDestroy(s *terraform.State) error { site, err := networkmanagerDescribeSite(conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) if err != nil { - if isAWSErr(err, networkmanager.ErrCodeValidationException, "") { + if tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeValidationException, "") { return nil } return err diff --git a/internal/service/networkmanager/transit_gateway_registration.go b/internal/service/networkmanager/transit_gateway_registration.go index 97ea4f09eae..c831ba2dfb4 100644 --- a/internal/service/networkmanager/transit_gateway_registration.go +++ b/internal/service/networkmanager/transit_gateway_registration.go @@ -9,8 +9,10 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) func ResourceTransitGatewayRegistration() *schema.Resource { @@ -93,7 +95,7 @@ func ResourceTransitGatewayRegistrationRead(d *schema.ResourceData, meta interfa transitGatewayRegistration, err := networkmanagerDescribeTransitGatewayRegistration(conn, d.Get("global_network_id").(string), d.Get("transit_gateway_arn").(string)) - if isAWSErr(err, "InvalidTransitGatewayRegistrationID.NotFound", "") { + if tfawserr.ErrCodeEquals(err, "InvalidTransitGatewayRegistrationID.NotFound", "") { log.Printf("[WARN] Network Manager Transit Gateway Registration (%s) not found, removing from state", d.Id()) d.SetId("") return nil @@ -130,7 +132,7 @@ func ResourceTransitGatewayRegistrationDelete(d *schema.ResourceData, meta inter req, _ := conn.DeregisterTransitGatewayRequest(input) err := req.Send() - if isAWSErr(err, "InvalidTransitGatewayRegistrationArn.NotFound", "") { + if tfawserr.ErrCodeEquals(err, "InvalidTransitGatewayRegistrationArn.NotFound", "") { return nil } @@ -149,7 +151,7 @@ func networkmanagerTransitGatewayRegistrationRefreshFunc(conn *networkmanager.Ne return func() (interface{}, string, error) { transitGatewayRegistration, err := networkmanagerDescribeTransitGatewayRegistration(conn, globalNetworkID, transitGatewayArn) - if isAWSErr(err, "InvalidTransitGatewayRegistrationID.NotFound", "") { + if tfawserr.ErrCodeEquals(err, "InvalidTransitGatewayRegistrationID.NotFound", "") { return nil, "DELETED", nil } @@ -220,7 +222,7 @@ func waitForTransitGatewayRegistrationDeletion(conn *networkmanager.NetworkManag log.Printf("[DEBUG] Waiting for Network Manager Transit Gateway Registration (%s) deletion", transitGatewayArn) _, err := stateConf.WaitForState() - if isResourceNotFoundError(err) { + if tfresource.NotFound(err) { return nil } diff --git a/internal/service/networkmanager/transit_gateway_registration_test.go b/internal/service/networkmanager/transit_gateway_registration_test.go index c93ec058cc9..3bc0637e8f7 100644 --- a/internal/service/networkmanager/transit_gateway_registration_test.go +++ b/internal/service/networkmanager/transit_gateway_registration_test.go @@ -7,9 +7,12 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/ec2" ) func init() { @@ -37,7 +40,7 @@ func testSweepTransitGatewayRegistration(region string) error { log.Printf("[INFO] Deleting Network Manager Transit Gateway Registration: %s", transitGatewayArn) req, _ := conn.DeregisterTransitGatewayRequest(input) err = req.Send() - if isAWSErr(err, "InvalidTransitGatewayRegistrationArn.NotFound", "") { + if tfawserr.ErrCodeEquals(err, "InvalidTransitGatewayRegistrationArn.NotFound", "") { continue } if err != nil { @@ -70,7 +73,7 @@ func TestAccTransitGatewayRegistration_basic(t *testing.T) { gloablNetwork2ResourceName := "aws_networkmanager_global_network.test2" transitGatewayResourceName := "aws_ec2_transit_gateway.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSEc2TransitGateway(t) }, + PreCheck: func() { acctest.PreCheck(t); ec2.testAccPreCheckTransitGateway(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAwsTransitGatewayRegistrationDestroy, Steps: []resource.TestStep{ @@ -107,7 +110,7 @@ func testAccCheckAwsTransitGatewayRegistrationDestroy(s *terraform.State) error } transitGatewayArn, err := networkmanagerDescribeTransitGatewayRegistration(conn, rs.Primary.Attributes["global_network_id"], rs.Primary.Attributes["transit_gateway_arn"]) if err != nil { - if isAWSErr(err, networkmanager.ErrCodeValidationException, "") { + if tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeValidationException, "") { return nil } return err From 50ccce67f3b078605406c0b6d03ff04d2e40083e Mon Sep 17 00:00:00 2001 From: nikhil Date: Fri, 30 Apr 2021 16:17:11 +0530 Subject: [PATCH 034/229] f/aws_iot_topic_rule:cloudwatchLogs action --- internal/service/iot/topic_rule.go | 152 ++++++++++++++++++++ internal/service/iot/topic_rule_test.go | 42 ++++++ website/docs/r/iot_topic_rule.html.markdown | 7 +- 3 files changed, 200 insertions(+), 1 deletion(-) diff --git a/internal/service/iot/topic_rule.go b/internal/service/iot/topic_rule.go index ecc0a43de41..63e1c7bf10b 100644 --- a/internal/service/iot/topic_rule.go +++ b/internal/service/iot/topic_rule.go @@ -58,6 +58,23 @@ func ResourceTopicRule() *schema.Resource { }, }, }, + "cloudwatch_logs": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "log_group_name": { + Type: schema.TypeString, + Required: true, + }, + "role_arn": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateArn, + }, + }, + }, + }, "cloudwatch_metric": { Type: schema.TypeSet, Optional: true, @@ -463,6 +480,43 @@ func ResourceTopicRule() *schema.Resource { }, ExactlyOneOf: []string{ "error_action.0.cloudwatch_alarm", + "error_action.0.cloudwatch_logs", + "error_action.0.cloudwatch_metric", + "error_action.0.dynamodb", + "error_action.0.dynamodbv2", + "error_action.0.elasticsearch", + "error_action.0.firehose", + "error_action.0.iot_analytics", + "error_action.0.iot_events", + "error_action.0.kinesis", + "error_action.0.lambda", + "error_action.0.republish", + "error_action.0.s3", + "error_action.0.step_functions", + "error_action.0.sns", + "error_action.0.sqs", + }, + }, + "cloudwatch_logs": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "log_group_name": { + Type: schema.TypeString, + Required: true, + }, + "role_arn": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateArn, + }, + }, + }, + ExactlyOneOf: []string{ + "error_action.0.cloudwatch_alarm", + "error_action.0.cloudwatch_logs", "error_action.0.cloudwatch_metric", "error_action.0.dynamodb", "error_action.0.dynamodbv2", @@ -515,6 +569,7 @@ func ResourceTopicRule() *schema.Resource { }, ExactlyOneOf: []string{ "error_action.0.cloudwatch_alarm", + "error_action.0.cloudwatch_logs", "error_action.0.cloudwatch_metric", "error_action.0.dynamodb", "error_action.0.dynamodbv2", @@ -587,6 +642,7 @@ func ResourceTopicRule() *schema.Resource { }, ExactlyOneOf: []string{ "error_action.0.cloudwatch_alarm", + "error_action.0.cloudwatch_logs", "error_action.0.cloudwatch_metric", "error_action.0.dynamodb", "error_action.0.dynamodbv2", @@ -631,6 +687,7 @@ func ResourceTopicRule() *schema.Resource { }, ExactlyOneOf: []string{ "error_action.0.cloudwatch_alarm", + "error_action.0.cloudwatch_logs", "error_action.0.cloudwatch_metric", "error_action.0.dynamodb", "error_action.0.dynamodbv2", @@ -679,6 +736,7 @@ func ResourceTopicRule() *schema.Resource { }, ExactlyOneOf: []string{ "error_action.0.cloudwatch_alarm", + "error_action.0.cloudwatch_logs", "error_action.0.cloudwatch_metric", "error_action.0.dynamodb", "error_action.0.dynamodbv2", @@ -719,6 +777,7 @@ func ResourceTopicRule() *schema.Resource { }, ExactlyOneOf: []string{ "error_action.0.cloudwatch_alarm", + "error_action.0.cloudwatch_logs", "error_action.0.cloudwatch_metric", "error_action.0.dynamodb", "error_action.0.dynamodbv2", @@ -754,6 +813,7 @@ func ResourceTopicRule() *schema.Resource { }, ExactlyOneOf: []string{ "error_action.0.cloudwatch_alarm", + "error_action.0.cloudwatch_logs", "error_action.0.cloudwatch_metric", "error_action.0.dynamodb", "error_action.0.dynamodbv2", @@ -793,6 +853,7 @@ func ResourceTopicRule() *schema.Resource { }, ExactlyOneOf: []string{ "error_action.0.cloudwatch_alarm", + "error_action.0.cloudwatch_logs", "error_action.0.cloudwatch_metric", "error_action.0.dynamodb", "error_action.0.dynamodbv2", @@ -832,6 +893,7 @@ func ResourceTopicRule() *schema.Resource { }, ExactlyOneOf: []string{ "error_action.0.cloudwatch_alarm", + "error_action.0.cloudwatch_logs", "error_action.0.cloudwatch_metric", "error_action.0.dynamodb", "error_action.0.dynamodbv2", @@ -863,6 +925,7 @@ func ResourceTopicRule() *schema.Resource { }, ExactlyOneOf: []string{ "error_action.0.cloudwatch_alarm", + "error_action.0.cloudwatch_logs", "error_action.0.cloudwatch_metric", "error_action.0.dynamodb", "error_action.0.dynamodbv2", @@ -904,6 +967,7 @@ func ResourceTopicRule() *schema.Resource { }, ExactlyOneOf: []string{ "error_action.0.cloudwatch_alarm", + "error_action.0.cloudwatch_logs", "error_action.0.cloudwatch_metric", "error_action.0.dynamodb", "error_action.0.dynamodbv2", @@ -943,6 +1007,7 @@ func ResourceTopicRule() *schema.Resource { }, ExactlyOneOf: []string{ "error_action.0.cloudwatch_alarm", + "error_action.0.cloudwatch_logs", "error_action.0.cloudwatch_metric", "error_action.0.dynamodb", "error_action.0.dynamodbv2", @@ -982,6 +1047,7 @@ func ResourceTopicRule() *schema.Resource { }, ExactlyOneOf: []string{ "error_action.0.cloudwatch_alarm", + "error_action.0.cloudwatch_logs", "error_action.0.cloudwatch_metric", "error_action.0.dynamodb", "error_action.0.dynamodbv2", @@ -1023,6 +1089,7 @@ func ResourceTopicRule() *schema.Resource { }, ExactlyOneOf: []string{ "error_action.0.cloudwatch_alarm", + "error_action.0.cloudwatch_logs", "error_action.0.cloudwatch_metric", "error_action.0.dynamodb", "error_action.0.dynamodbv2", @@ -1062,6 +1129,7 @@ func ResourceTopicRule() *schema.Resource { }, ExactlyOneOf: []string{ "error_action.0.cloudwatch_alarm", + "error_action.0.cloudwatch_logs", "error_action.0.cloudwatch_metric", "error_action.0.dynamodb", "error_action.0.dynamodbv2", @@ -1175,6 +1243,10 @@ func resourceTopicRuleRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("error setting cloudwatch_alarm: %w", err) } + if err := d.Set("cloudwatch_logs", flattenIotCloudWatchLogsActions(out.Rule.Actions)); err != nil { + return fmt.Errorf("error setting cloudwatch_logs: %w", err) + } + if err := d.Set("cloudwatch_metric", flattenIotCloudwatchMetricActions(out.Rule.Actions)); err != nil { return fmt.Errorf("error setting cloudwatch_metric: %w", err) } @@ -1243,6 +1315,7 @@ func resourceTopicRuleUpdate(d *schema.ResourceData, meta interface{}) error { if d.HasChanges( "cloudwatch_alarm", + "cloudwatch_logs", "cloudwatch_metric", "description", "dynamodb", @@ -1344,6 +1417,25 @@ func expandIotCloudwatchAlarmAction(tfList []interface{}) *iot.CloudwatchAlarmAc return apiObject } +func expandIotCloudwatchLogsAction(tfList []interface{}) *iot.CloudwatchLogsAction { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + apiObject := &iot.CloudwatchLogsAction{} + tfMap := tfList[0].(map[string]interface{}) + + if v, ok := tfMap["log_group_name"].(string); ok && v != "" { + apiObject.LogGroupName = aws.String(v) + } + + if v, ok := tfMap["role_arn"].(string); ok && v != "" { + apiObject.RoleArn = aws.String(v) + } + + return apiObject +} + func expandIotCloudwatchMetricAction(tfList []interface{}) *iot.CloudwatchMetricAction { if len(tfList) == 0 || tfList[0] == nil { return nil @@ -1712,6 +1804,17 @@ func expandIotTopicRulePayload(d *schema.ResourceData) *iot.TopicRulePayload { actions = append(actions, &iot.Action{CloudwatchAlarm: action}) } + // Legacy root attribute handling + for _, tfMapRaw := range d.Get("cloudwatch_logs").(*schema.Set).List() { + action := expandIotCloudwatchLogsAction([]interface{}{tfMapRaw}) + + if action == nil { + continue + } + + actions = append(actions, &iot.Action{CloudwatchLogs: action}) + } + // Legacy root attribute handling for _, tfMapRaw := range d.Get("cloudwatch_metric").(*schema.Set).List() { action := expandIotCloudwatchMetricAction([]interface{}{tfMapRaw}) @@ -1887,6 +1990,16 @@ func expandIotTopicRulePayload(d *schema.ResourceData) *iot.TopicRulePayload { iotErrorAction = &iot.Action{CloudwatchAlarm: action} } + case "cloudwatch_logs": + for _, tfMapRaw := range v.([]interface{}) { + action := expandIotCloudwatchLogsAction([]interface{}{tfMapRaw}) + + if action == nil { + continue + } + + iotErrorAction = &iot.Action{CloudwatchLogs: action} + } case "cloudwatch_metric": for _, tfMapRaw := range v.([]interface{}) { action := expandIotCloudwatchMetricAction([]interface{}{tfMapRaw}) @@ -2084,6 +2197,41 @@ func flattenIotCloudWatchAlarmActions(actions []*iot.Action) []interface{} { return results } +func flattenIotCloudwatchLogsAction(apiObject *iot.CloudwatchLogsAction) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := make(map[string]interface{}) + + if v := apiObject.LogGroupName; v != nil { + tfMap["log_group_name"] = aws.StringValue(v) + } + + if v := apiObject.RoleArn; v != nil { + tfMap["role_arn"] = aws.StringValue(v) + } + + return []interface{}{tfMap} +} + +// Legacy root attribute handling +func flattenIotCloudWatchLogsActions(actions []*iot.Action) []interface{} { + results := make([]interface{}, 0) + + for _, action := range actions { + if action == nil { + continue + } + + if v := action.CloudwatchLogs; v != nil { + results = append(results, flattenIotCloudwatchLogsAction(v)...) + } + } + + return results +} + // Legacy root attribute handling func flattenIotCloudwatchMetricActions(actions []*iot.Action) []interface{} { results := make([]interface{}, 0) @@ -2665,6 +2813,10 @@ func flattenIotErrorAction(errorAction *iot.Action) []map[string]interface{} { results = append(results, map[string]interface{}{"cloudwatch_alarm": flattenIotCloudWatchAlarmActions(input)}) return results } + if errorAction.CloudwatchLogs != nil { + results = append(results, map[string]interface{}{"cloudwatch_logs": flattenIotCloudWatchLogsActions(input)}) + return results + } if errorAction.CloudwatchMetric != nil { results = append(results, map[string]interface{}{"cloudwatch_metric": flattenIotCloudwatchMetricActions(input)}) return results diff --git a/internal/service/iot/topic_rule_test.go b/internal/service/iot/topic_rule_test.go index 3705b3f72e9..103949ddb5f 100644 --- a/internal/service/iot/topic_rule_test.go +++ b/internal/service/iot/topic_rule_test.go @@ -69,6 +69,31 @@ func TestAccIoTTopicRule_cloudWatchAlarm(t *testing.T) { }) } +func TestAccIoTTopicRule_cloudWatchLogs(t *testing.T) { + rName := acctest.RandString(5) + resourceName := "aws_iot_topic_rule.rule" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, iot.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSIoTTopicRuleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccIoTTopicRule_cloudWatchLogs(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccIoTTopicRule_cloudWatchMetric(t *testing.T) { rName := sdkacctest.RandString(5) resourceName := "aws_iot_topic_rule.rule" @@ -705,6 +730,23 @@ resource "aws_iot_topic_rule" "rule" { `, rName)) } +func testAccIoTTopicRule_cloudWatchLogs(rName string) string { + return fmt.Sprintf(testAccIoTTopicRuleRole+` +resource "aws_iot_topic_rule" "rule" { + name = "test_rule_%[1]s" + description = "Example rule" + enabled = true + sql = "SELECT * FROM 'topic/test'" + sql_version = "2015-10-08" + + cloudwatch_logs { + log_group_name = "mylogs" + role_arn = aws_iam_role.iot_role.arn + } +} +`, rName) +} + func testAccTopicRule_cloudWatchmetric(rName string) string { return acctest.ConfigCompose( testAccTopicRuleRole(rName), diff --git a/website/docs/r/iot_topic_rule.html.markdown b/website/docs/r/iot_topic_rule.html.markdown index fbe52a1f0ef..ac31f87fbdd 100644 --- a/website/docs/r/iot_topic_rule.html.markdown +++ b/website/docs/r/iot_topic_rule.html.markdown @@ -88,7 +88,7 @@ EOF * `enabled` - (Required) Specifies whether the rule is enabled. * `sql` - (Required) The SQL statement used to query the topic. For more information, see AWS IoT SQL Reference (http://docs.aws.amazon.com/iot/latest/developerguide/iot-rules.html#aws-iot-sql-reference) in the AWS IoT Developer Guide. * `sql_version` - (Required) The version of the SQL rules engine to use when evaluating the rule. -* `error_action` - (Optional) Configuration block with error action to be associated with the rule. See the documentation for `cloudwatch_alarm`, `cloudwatch_metric`, `dynamodb`, `dynamodbv2`, `elasticsearch`, `firehose`, `iot_analytics`, `iot_events`, `kinesis`, `lambda`, `republish`, `s3`, `step_functions`, `sns`, `sqs` configuration blocks for further configuration details. +* `error_action` - (Optional) Configuration block with error action to be associated with the rule. See the documentation for `cloudwatch_alarm`, `cloudwatch_logs`, `cloudwatch_metric`, `dynamodb`, `dynamodbv2`, `elasticsearch`, `firehose`, `iot_analytics`, `iot_events`, `kinesis`, `lambda`, `republish`, `s3`, `step_functions`, `sns`, `sqs` configuration blocks for further configuration details. * `tags` - (Optional) Key-value map of resource tags. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. The `cloudwatch_alarm` object takes the following arguments: @@ -98,6 +98,11 @@ The `cloudwatch_alarm` object takes the following arguments: * `state_reason` - (Required) The reason for the alarm change. * `state_value` - (Required) The value of the alarm state. Acceptable values are: OK, ALARM, INSUFFICIENT_DATA. +The `cloudwatch_logs` object takes the following arguments: + +* `log_group_name` - (Required) The CloudWatch log group name. +* `role_arn` - (Required) The IAM role ARN that allows access to the CloudWatch alarm. + The `cloudwatch_metric` object takes the following arguments: * `metric_name` - (Required) The CloudWatch metric name. From 5f08e1ea3ec94aa4e7e18d2fa27763d8e8c4578d Mon Sep 17 00:00:00 2001 From: Eldon Stegall Date: Tue, 1 Mar 2022 14:21:29 -0500 Subject: [PATCH 035/229] f/aws_iot_topic_rule:cloudwatchLogs action update tests --- internal/service/iot/topic_rule.go | 4 ++-- internal/service/iot/topic_rule_test.go | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/internal/service/iot/topic_rule.go b/internal/service/iot/topic_rule.go index 63e1c7bf10b..78cfce7af8e 100644 --- a/internal/service/iot/topic_rule.go +++ b/internal/service/iot/topic_rule.go @@ -70,7 +70,7 @@ func ResourceTopicRule() *schema.Resource { "role_arn": { Type: schema.TypeString, Required: true, - ValidateFunc: validateArn, + ValidateFunc: verify.ValidARN, }, }, }, @@ -510,7 +510,7 @@ func ResourceTopicRule() *schema.Resource { "role_arn": { Type: schema.TypeString, Required: true, - ValidateFunc: validateArn, + ValidateFunc: verify.ValidARN, }, }, }, diff --git a/internal/service/iot/topic_rule_test.go b/internal/service/iot/topic_rule_test.go index 103949ddb5f..b2f3833312f 100644 --- a/internal/service/iot/topic_rule_test.go +++ b/internal/service/iot/topic_rule_test.go @@ -70,19 +70,19 @@ func TestAccIoTTopicRule_cloudWatchAlarm(t *testing.T) { } func TestAccIoTTopicRule_cloudWatchLogs(t *testing.T) { - rName := acctest.RandString(5) + rName := sdkacctest.RandString(5) resourceName := "aws_iot_topic_rule.rule" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, iot.EndpointsID), - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSIoTTopicRuleDestroy, + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, iot.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckTopicRuleDestroy, Steps: []resource.TestStep{ { Config: testAccIoTTopicRule_cloudWatchLogs(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSIoTTopicRuleExists("aws_iot_topic_rule.rule"), + testAccCheckTopicRuleExists("aws_iot_topic_rule.rule"), ), }, { @@ -731,7 +731,9 @@ resource "aws_iot_topic_rule" "rule" { } func testAccIoTTopicRule_cloudWatchLogs(rName string) string { - return fmt.Sprintf(testAccIoTTopicRuleRole+` + return acctest.ConfigCompose( + testAccTopicRuleRole(rName), + fmt.Sprintf(` resource "aws_iot_topic_rule" "rule" { name = "test_rule_%[1]s" description = "Example rule" @@ -744,7 +746,7 @@ resource "aws_iot_topic_rule" "rule" { role_arn = aws_iam_role.iot_role.arn } } -`, rName) +`, rName)) } func testAccTopicRule_cloudWatchmetric(rName string) string { From 06f86b8a7ff3ed1200fb3cf381219c1e8d0ac2fd Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 10:31:59 -0500 Subject: [PATCH 036/229] Revert "Fixing linter issues" This reverts commit ffd7a1640705ed358f5ae165d65ec47418e68855. --- .../service/networkmanager/global_network_test.go | 13 +++++-------- .../r/networkmanager_global_network.html.markdown | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/internal/service/networkmanager/global_network_test.go b/internal/service/networkmanager/global_network_test.go index fcc4a8ca0f0..21a8c0382c3 100644 --- a/internal/service/networkmanager/global_network_test.go +++ b/internal/service/networkmanager/global_network_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/apigateway" nm "github.com/aws/aws-sdk-go/service/networkmanager" "github.com/hashicorp/aws-sdk-go-base/tfawserr" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" @@ -24,7 +25,6 @@ func TestAccNetworkManagerGlobalNetwork_basic(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, Providers: acctest.Providers, CheckDestroy: testAccCheckResourceGlobalNetworkDestroy, - ErrorCheck: acctest.ErrorCheck(t, nm.EndpointsID), Steps: []resource.TestStep{ { Config: testAccresourceGlobalNetworkConfig(), @@ -53,7 +53,6 @@ func TestAccNetworkManagerGlobalNetwork_tags(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, Providers: acctest.Providers, CheckDestroy: testAccCheckResourceGlobalNetworkDestroy, - ErrorCheck: acctest.ErrorCheck(t, nm.EndpointsID), Steps: []resource.TestStep{ { Config: testAccresourceGlobalNetworkTagsConfig(rName, "key1", "value1"), @@ -98,7 +97,7 @@ func TestAccNetworkManagerGlobalNetwork_description(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, - ErrorCheck: acctest.ErrorCheck(t, nm.EndpointsID), + ErrorCheck: acctest.ErrorCheck(t, apigateway.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckResourceGlobalNetworkDestroy, Steps: []resource.TestStep{ @@ -167,12 +166,10 @@ func testAccCheckResourceGlobalNetworkExists(resourceName string, globalNetwork } conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn - - var err error - globalNetwork, err = networkmanager.DescribeGlobalNetwork(conn, rs.Primary.ID) + globalNetwork, err := networkmanager.DescribeGlobalNetwork(conn, rs.Primary.ID) if err != nil { - return fmt.Errorf("Error describing Global Network: %s", err) + return nil } if globalNetwork == nil { @@ -180,7 +177,7 @@ func testAccCheckResourceGlobalNetworkExists(resourceName string, globalNetwork } if aws.StringValue(globalNetwork.State) != nm.GlobalNetworkStateAvailable { - return fmt.Errorf("Network Manager Global Network (%s) exists in non-available (%s) state", rs.Primary.ID, aws.StringValue(globalNetwork.State)) + return fmt.Errorf("Network Manager Global Netowrk (%s) exists in non-available (%s) state", rs.Primary.ID, aws.StringValue(globalNetwork.State)) } return nil diff --git a/website/docs/r/networkmanager_global_network.html.markdown b/website/docs/r/networkmanager_global_network.html.markdown index 0dbab47db8a..5f7d425dda0 100644 --- a/website/docs/r/networkmanager_global_network.html.markdown +++ b/website/docs/r/networkmanager_global_network.html.markdown @@ -12,7 +12,7 @@ Provides a global network resource. ## Example Usage -```terraform +```hcl resource "aws_networkmanager_global_network" "example" { description = "example" } From 9439351c6a08b621195e8f7d3fd05e625a69d13e Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 10:32:09 -0500 Subject: [PATCH 037/229] Revert "Adding changelog" This reverts commit 13c8114fc7956335fdf4c5ca46b53a4bbde623e4. --- .changelog/21789.txt | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .changelog/21789.txt diff --git a/.changelog/21789.txt b/.changelog/21789.txt deleted file mode 100644 index 4ef1e831c56..00000000000 --- a/.changelog/21789.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:new-resource -aws_networkmanager_global_network -``` \ No newline at end of file From f72ec591c185ed728da0ea0b0682ef8540d21779 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 10:32:18 -0500 Subject: [PATCH 038/229] Revert "New resource/aws_networkmanager_global_network" This reverts commit d6d6a321f102b8ab2f2c169a620f73cc8606ce44. --- internal/provider/provider.go | 3 - .../service/networkmanager/global_network.go | 278 ------------------ .../networkmanager/global_network_test.go | 227 -------------- ...etworkmanager_global_network.html.markdown | 40 --- 4 files changed, 548 deletions(-) delete mode 100644 internal/service/networkmanager/global_network.go delete mode 100644 internal/service/networkmanager/global_network_test.go delete mode 100644 website/docs/r/networkmanager_global_network.html.markdown diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 042ba10cc81..417c3cba0bb 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -105,7 +105,6 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/service/mwaa" "github.com/hashicorp/terraform-provider-aws/internal/service/neptune" "github.com/hashicorp/terraform-provider-aws/internal/service/networkfirewall" - "github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager" "github.com/hashicorp/terraform-provider-aws/internal/service/opsworks" "github.com/hashicorp/terraform-provider-aws/internal/service/organizations" "github.com/hashicorp/terraform-provider-aws/internal/service/outposts" @@ -1358,8 +1357,6 @@ func Provider() *schema.Provider { "aws_networkfirewall_resource_policy": networkfirewall.ResourceResourcePolicy(), "aws_networkfirewall_rule_group": networkfirewall.ResourceRuleGroup(), - "aws_networkmanager_global_network": networkmanager.ResourceGlobalNetwork(), - "aws_opsworks_application": opsworks.ResourceApplication(), "aws_opsworks_custom_layer": opsworks.ResourceCustomLayer(), "aws_opsworks_ganglia_layer": opsworks.ResourceGangliaLayer(), diff --git a/internal/service/networkmanager/global_network.go b/internal/service/networkmanager/global_network.go deleted file mode 100644 index a8bf59ee916..00000000000 --- a/internal/service/networkmanager/global_network.go +++ /dev/null @@ -1,278 +0,0 @@ -package networkmanager - -import ( - "fmt" - "log" - "time" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-provider-aws/internal/conns" - tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" - "github.com/hashicorp/terraform-provider-aws/internal/tfresource" - "github.com/hashicorp/terraform-provider-aws/internal/verify" -) - -func ResourceGlobalNetwork() *schema.Resource { - return &schema.Resource{ - Create: resourceGlobalNetworkCreate, - Read: resourceGlobalNetworkRead, - Update: resourceGlobalNetworkUpdate, - Delete: resourceGlobalNetworkDelete, - - Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, - }, - - Timeouts: &schema.ResourceTimeout{ - Create: schema.DefaultTimeout(30 * time.Second), - Delete: schema.DefaultTimeout(30 * time.Second), - }, - - Schema: map[string]*schema.Schema{ - "arn": { - Type: schema.TypeString, - Computed: true, - }, - - "id": { - Type: schema.TypeString, - Computed: true, - }, - - "description": { - Type: schema.TypeString, - Optional: true, - Default: "", - }, - - "tags": tftags.TagsSchema(), - "tags_all": tftags.TagsSchemaComputed(), - }, - - CustomizeDiff: verify.SetTagsDiff, - } -} - -func resourceGlobalNetworkCreate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*conns.AWSClient).NetworkManagerConn - defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig - tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{}))) - - input := &networkmanager.CreateGlobalNetworkInput{} - - if v, ok := d.GetOk("description"); ok { - input.Description = aws.String(v.(string)) - } - - if len(tags) > 0 { - input.Tags = Tags(tags.IgnoreAWS()) - } - - log.Println("[DEBUG] Creating Global Network:", input) - output, err := conn.CreateGlobalNetwork(input) - if err != nil { - return fmt.Errorf("Error creating Global Network: %s", err) - } - - d.SetId(aws.StringValue(output.GlobalNetwork.GlobalNetworkId)) - - if err := waitForNetworkManagerGlobalNetworkCreation(conn, d.Id()); err != nil { - return fmt.Errorf("Error waiting for Global Network: %w", err) - } - - return resourceGlobalNetworkRead(d, meta) -} - -func resourceGlobalNetworkRead(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*conns.AWSClient).NetworkManagerConn - defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig - ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig - - output, err := DescribeGlobalNetwork(conn, d.Id()) - - if tfawserr.ErrMessageContains(err, networkmanager.ErrCodeResourceNotFoundException, "") { - log.Printf("[WARN] No Global Networks by ID (%s) found, removing from state", d.Id()) - d.SetId("") - return nil - } - - if err != nil { - return fmt.Errorf("Error reading Global Network %s: %s", d.Id(), err) - } - - if output == nil { - log.Printf("[WARN] No Global Networks by ID (%s) found, removing from state", d.Id()) - d.SetId("") - return nil - } - - if aws.StringValue(output.State) != networkmanager.ConnectionStateAvailable { - log.Printf("[WARN] Global Networks (%s) delet(ing|ed), removing from state", d.Id()) - d.SetId("") - return nil - } - - d.Set("arn", output.GlobalNetworkArn) - d.Set("description", output.Description) - - tags := KeyValueTags(output.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) - - //lintignore:AWSR002 - if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { - return fmt.Errorf("Error setting tags: %w", err) - } - - if err := d.Set("tags_all", tags.Map()); err != nil { - return fmt.Errorf("Error setting tags_all: %w", err) - } - - return nil - -} - -func resourceGlobalNetworkUpdate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*conns.AWSClient).NetworkManagerConn - - if d.HasChanges("description") { - request := &networkmanager.UpdateGlobalNetworkInput{ - GlobalNetworkId: aws.String(d.Id()), - Description: aws.String(d.Get("description").(string)), - } - - log.Println("[DEBUG] Update Global Network request:", request) - _, err := conn.UpdateGlobalNetwork(request) - if err != nil { - if tfawserr.ErrMessageContains(err, networkmanager.ErrCodeResourceNotFoundException, "") { - log.Printf("[WARN] No Global Network by ID (%s) found", d.Id()) - d.SetId("") - return nil - } - return fmt.Errorf("Error updating Global Network %s: %s", d.Id(), err) - } - - } - - if d.HasChange("tags_all") { - o, n := d.GetChange("tags_all") - - if err := UpdateTags(conn, d.Get("arn").(string), o, n); err != nil { - return fmt.Errorf("Error updating Global Network (%s) tags: %s", d.Id(), err) - } - } - - return resourceGlobalNetworkRead(d, meta) - -} - -func resourceGlobalNetworkDelete(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*conns.AWSClient).NetworkManagerConn - - input := &networkmanager.DeleteGlobalNetworkInput{ - GlobalNetworkId: aws.String(d.Id()), - } - - log.Println("[DEBUG] Delete Global Network request:", input) - _, err := conn.DeleteGlobalNetwork(input) - if err != nil { - return fmt.Errorf("Error deleting Global Network: %s", err) - } - - if err := waitForNetworkManagerGlobalNetworkDeletion(conn, d.Id()); err != nil { - return fmt.Errorf("Error waiting for Global Network (%s) deletion: %s", d.Id(), err) - } - - return nil -} - -func networkManagerGlobalNetworkRefresh(conn *networkmanager.NetworkManager, globalNetworkId string) resource.StateRefreshFunc { - return func() (interface{}, string, error) { - networkManagerGlobalNetwork, err := DescribeGlobalNetwork(conn, globalNetworkId) - if tfawserr.ErrMessageContains(err, networkmanager.ErrCodeResourceNotFoundException, "") { - return nil, networkmanager.GlobalNetworkStateDeleting, nil - } - - if err != nil { - return nil, "", fmt.Errorf("Error reading Global Network (%s): %s", globalNetworkId, err) - } - - if networkManagerGlobalNetwork == nil { - return nil, networkmanager.GlobalNetworkStateDeleting, nil - } - - return networkManagerGlobalNetwork, aws.StringValue(networkManagerGlobalNetwork.State), nil - } -} - -func DescribeGlobalNetwork(conn *networkmanager.NetworkManager, globalNetworkID string) (*networkmanager.GlobalNetwork, error) { - request := &networkmanager.DescribeGlobalNetworksInput{ - GlobalNetworkIds: []*string{aws.String(globalNetworkID)}, - } - - log.Printf("[DEBUG] Reading Global Network (%s): %s", globalNetworkID, request) - for { - output, err := conn.DescribeGlobalNetworks(request) - - if err != nil { - return nil, err - } - - if output == nil || len(output.GlobalNetworks) == 0 { - return nil, nil - } - - for _, globalNetwork := range output.GlobalNetworks { - if globalNetwork == nil { - continue - } - - if aws.StringValue(globalNetwork.GlobalNetworkId) == globalNetworkID { - return globalNetwork, nil - } - } - - if aws.StringValue(output.NextToken) == "" { - break - } - - request.NextToken = output.NextToken - } - - return nil, nil -} - -func waitForNetworkManagerGlobalNetworkCreation(conn *networkmanager.NetworkManager, globalNetworkId string) error { - stateConf := &resource.StateChangeConf{ - Pending: []string{networkmanager.GlobalNetworkStatePending}, - Target: []string{networkmanager.GlobalNetworkStateAvailable}, - Refresh: networkManagerGlobalNetworkRefresh(conn, globalNetworkId), - Timeout: 10 * time.Minute, - } - - log.Printf("[DEBUG] Waiting for Global Network (%s) creation", globalNetworkId) - _, err := stateConf.WaitForState() - - return err -} - -func waitForNetworkManagerGlobalNetworkDeletion(conn *networkmanager.NetworkManager, globalNetworkId string) error { - stateConf := &resource.StateChangeConf{ - Pending: []string{networkmanager.GlobalNetworkStateAvailable}, - Target: []string{networkmanager.GlobalNetworkStateDeleting}, - Refresh: networkManagerGlobalNetworkRefresh(conn, globalNetworkId), - Timeout: 10 * time.Minute, - NotFoundChecks: 1, - } - - log.Printf("[DEBUG] Waiting for Global Network (%s) deletion", globalNetworkId) - _, err := stateConf.WaitForState() - - if tfresource.NotFound(err) { - return nil - } - - return err -} diff --git a/internal/service/networkmanager/global_network_test.go b/internal/service/networkmanager/global_network_test.go deleted file mode 100644 index 21a8c0382c3..00000000000 --- a/internal/service/networkmanager/global_network_test.go +++ /dev/null @@ -1,227 +0,0 @@ -package networkmanager_test - -import ( - "fmt" - "regexp" - "testing" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/apigateway" - nm "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" - 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" - "github.com/hashicorp/terraform-provider-aws/internal/acctest" - "github.com/hashicorp/terraform-provider-aws/internal/conns" - "github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager" -) - -func TestAccNetworkManagerGlobalNetwork_basic(t *testing.T) { - var globalNetwork nm.GlobalNetwork - resourceName := "aws_networkmanager_global_network.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t) }, - Providers: acctest.Providers, - CheckDestroy: testAccCheckResourceGlobalNetworkDestroy, - Steps: []resource.TestStep{ - { - Config: testAccresourceGlobalNetworkConfig(), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceGlobalNetworkExists(resourceName, &globalNetwork), - acctest.MatchResourceAttrGlobalARN(resourceName, "arn", "networkmanager", regexp.MustCompile(`global-network/global-network-.+`)), - resource.TestCheckResourceAttr(resourceName, "description", ""), - resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccNetworkManagerGlobalNetwork_tags(t *testing.T) { - var globalNetwork nm.GlobalNetwork - resourceName := "aws_networkmanager_global_network.test" - rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t) }, - Providers: acctest.Providers, - CheckDestroy: testAccCheckResourceGlobalNetworkDestroy, - Steps: []resource.TestStep{ - { - Config: testAccresourceGlobalNetworkTagsConfig(rName, "key1", "value1"), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceGlobalNetworkExists(resourceName, &globalNetwork), - resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), - resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), - resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), - ), - }, - { - Config: testAccresourceGlobalNetworkTagsConfig(rName, "key1", "value1"), - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccresourceGlobalNetworkTags2Config(rName, "key1", "value1updated", "key2", "value2"), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceGlobalNetworkExists(resourceName, &globalNetwork), - resource.TestCheckResourceAttr(resourceName, "tags.%", "3"), - resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), - resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), - resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), - ), - }, - { - Config: testAccresourceGlobalNetworkConfig(), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceGlobalNetworkExists(resourceName, &globalNetwork), - resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), - ), - }, - }, - }) -} - -func TestAccNetworkManagerGlobalNetwork_description(t *testing.T) { - var globalNetwork nm.GlobalNetwork - rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - resourceName := "aws_networkmanager_global_network.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t) }, - ErrorCheck: acctest.ErrorCheck(t, apigateway.EndpointsID), - Providers: acctest.Providers, - CheckDestroy: testAccCheckResourceGlobalNetworkDestroy, - Steps: []resource.TestStep{ - { - Config: testAccresourceGlobalNetworkDescriptionConfig(rName, "description1"), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckResourceGlobalNetworkExists(resourceName, &globalNetwork), - resource.TestCheckResourceAttr(resourceName, "description", "description1"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccresourceGlobalNetworkDescriptionConfig(rName, "description2"), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckResourceGlobalNetworkExists(resourceName, &globalNetwork), - resource.TestCheckResourceAttr(resourceName, "description", "description2"), - ), - }, - }, - }) -} - -func testAccCheckResourceGlobalNetworkDestroy(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn - - for _, rs := range s.RootModule().Resources { - if rs.Type != "aws_networkmanager_global_network" { - continue - } - - output, err := networkmanager.DescribeGlobalNetwork(conn, rs.Primary.ID) - - if tfawserr.ErrMessageContains(err, nm.ErrCodeResourceNotFoundException, "") { - continue - } - - if err != nil { - return err - } - - if output == nil { - continue - } - - if aws.StringValue(output.State) != nm.GlobalNetworkStateDeleting { - return fmt.Errorf("Network Manager Global Network (%s) still exists in non-deleted (%s) state", rs.Primary.ID, aws.StringValue(output.State)) - } - } - - return nil -} - -func testAccCheckResourceGlobalNetworkExists(resourceName string, globalNetwork *nm.GlobalNetwork) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[resourceName] - if !ok { - return fmt.Errorf("Not found: %s", resourceName) - } - - if rs.Primary.ID == "" { - return fmt.Errorf("No Network Manager Global Network ID is set") - } - - conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn - globalNetwork, err := networkmanager.DescribeGlobalNetwork(conn, rs.Primary.ID) - - if err != nil { - return nil - } - - if globalNetwork == nil { - return fmt.Errorf("Network Manager Global Network not found") - } - - if aws.StringValue(globalNetwork.State) != nm.GlobalNetworkStateAvailable { - return fmt.Errorf("Network Manager Global Netowrk (%s) exists in non-available (%s) state", rs.Primary.ID, aws.StringValue(globalNetwork.State)) - } - - return nil - - } -} - -func testAccresourceGlobalNetworkConfig() string { - return ` -resource "aws_networkmanager_global_network" "test" { } -` -} - -func testAccresourceGlobalNetworkDescriptionConfig(rName, description string) string { - return fmt.Sprintf(` -resource "aws_networkmanager_global_network" "test" { - description = %[2]q - - tags = { - Name = %[1]q - } -} -`, rName, description) -} - -func testAccresourceGlobalNetworkTagsConfig(rName, tagKey1, tagValue1 string) string { - return fmt.Sprintf(` -resource "aws_networkmanager_global_network" "test" { - tags = { - Name = %[1]q - %[2]q = %[3]q - } -} -`, rName, tagKey1, tagValue1) -} - -func testAccresourceGlobalNetworkTags2Config(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { - return fmt.Sprintf(` -resource "aws_networkmanager_global_network" "test" { - tags = { - Name = %[1]q - %[2]q = %[3]q - %[4]q = %[5]q - } -} -`, rName, tagKey1, tagValue1, tagKey2, tagValue2) -} diff --git a/website/docs/r/networkmanager_global_network.html.markdown b/website/docs/r/networkmanager_global_network.html.markdown deleted file mode 100644 index 5f7d425dda0..00000000000 --- a/website/docs/r/networkmanager_global_network.html.markdown +++ /dev/null @@ -1,40 +0,0 @@ ---- -subcategory: "Transit Gateway Network Manager" -layout: "aws" -page_title: "AWS: aws_networkmanager_global_network" -description: |- - Provides a global network resource. ---- - -# Resource: aws_networkmanager_global_network - -Provides a global network resource. - -## Example Usage - -```hcl -resource "aws_networkmanager_global_network" "example" { - description = "example" -} -``` - -## Argument Reference - -The following arguments are supported: - -* `description` - (Optional) Description of the Global Network. -* `tags` - (Optional) Key-value tags for the Global Network. - -## Attributes Reference - -In addition to all arguments above, the following attributes are exported: - -* `arn` - Global Network Amazon Resource Name (ARN) - -## Import - -`aws_networkmanager_global_network` can be imported using the global network ID, e.g. - -``` -$ terraform import aws_networkmanager_global_network.example global-network-0d47f6t230mz46dy4 -``` \ No newline at end of file From 9f2cfc9a153cf000243eefef1097e991e856dec8 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 12:01:13 -0500 Subject: [PATCH 039/229] Temporarily move code not being worked on. --- internal/service/networkmanager/{ => ignore}/device.go | 0 .../service/networkmanager/{ => ignore}/device_data_source.go | 0 .../networkmanager/{ => ignore}/device_data_source_test.go | 0 internal/service/networkmanager/{ => ignore}/device_test.go | 0 internal/service/networkmanager/{ => ignore}/flex.go | 0 .../networkmanager/{ => ignore}/global_network_data_source.go | 0 .../{ => ignore}/global_network_data_source_test.go | 0 .../service/networkmanager/{ => ignore}/global_network_test.go | 0 internal/service/networkmanager/{ => ignore}/site.go | 0 internal/service/networkmanager/{ => ignore}/site_data_source.go | 0 .../service/networkmanager/{ => ignore}/site_data_source_test.go | 0 internal/service/networkmanager/{ => ignore}/site_test.go | 0 .../networkmanager/{ => ignore}/transit_gateway_registration.go | 0 .../{ => ignore}/transit_gateway_registration_test.go | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename internal/service/networkmanager/{ => ignore}/device.go (100%) rename internal/service/networkmanager/{ => ignore}/device_data_source.go (100%) rename internal/service/networkmanager/{ => ignore}/device_data_source_test.go (100%) rename internal/service/networkmanager/{ => ignore}/device_test.go (100%) rename internal/service/networkmanager/{ => ignore}/flex.go (100%) rename internal/service/networkmanager/{ => ignore}/global_network_data_source.go (100%) rename internal/service/networkmanager/{ => ignore}/global_network_data_source_test.go (100%) rename internal/service/networkmanager/{ => ignore}/global_network_test.go (100%) rename internal/service/networkmanager/{ => ignore}/site.go (100%) rename internal/service/networkmanager/{ => ignore}/site_data_source.go (100%) rename internal/service/networkmanager/{ => ignore}/site_data_source_test.go (100%) rename internal/service/networkmanager/{ => ignore}/site_test.go (100%) rename internal/service/networkmanager/{ => ignore}/transit_gateway_registration.go (100%) rename internal/service/networkmanager/{ => ignore}/transit_gateway_registration_test.go (100%) diff --git a/internal/service/networkmanager/device.go b/internal/service/networkmanager/ignore/device.go similarity index 100% rename from internal/service/networkmanager/device.go rename to internal/service/networkmanager/ignore/device.go diff --git a/internal/service/networkmanager/device_data_source.go b/internal/service/networkmanager/ignore/device_data_source.go similarity index 100% rename from internal/service/networkmanager/device_data_source.go rename to internal/service/networkmanager/ignore/device_data_source.go diff --git a/internal/service/networkmanager/device_data_source_test.go b/internal/service/networkmanager/ignore/device_data_source_test.go similarity index 100% rename from internal/service/networkmanager/device_data_source_test.go rename to internal/service/networkmanager/ignore/device_data_source_test.go diff --git a/internal/service/networkmanager/device_test.go b/internal/service/networkmanager/ignore/device_test.go similarity index 100% rename from internal/service/networkmanager/device_test.go rename to internal/service/networkmanager/ignore/device_test.go diff --git a/internal/service/networkmanager/flex.go b/internal/service/networkmanager/ignore/flex.go similarity index 100% rename from internal/service/networkmanager/flex.go rename to internal/service/networkmanager/ignore/flex.go diff --git a/internal/service/networkmanager/global_network_data_source.go b/internal/service/networkmanager/ignore/global_network_data_source.go similarity index 100% rename from internal/service/networkmanager/global_network_data_source.go rename to internal/service/networkmanager/ignore/global_network_data_source.go diff --git a/internal/service/networkmanager/global_network_data_source_test.go b/internal/service/networkmanager/ignore/global_network_data_source_test.go similarity index 100% rename from internal/service/networkmanager/global_network_data_source_test.go rename to internal/service/networkmanager/ignore/global_network_data_source_test.go diff --git a/internal/service/networkmanager/global_network_test.go b/internal/service/networkmanager/ignore/global_network_test.go similarity index 100% rename from internal/service/networkmanager/global_network_test.go rename to internal/service/networkmanager/ignore/global_network_test.go diff --git a/internal/service/networkmanager/site.go b/internal/service/networkmanager/ignore/site.go similarity index 100% rename from internal/service/networkmanager/site.go rename to internal/service/networkmanager/ignore/site.go diff --git a/internal/service/networkmanager/site_data_source.go b/internal/service/networkmanager/ignore/site_data_source.go similarity index 100% rename from internal/service/networkmanager/site_data_source.go rename to internal/service/networkmanager/ignore/site_data_source.go diff --git a/internal/service/networkmanager/site_data_source_test.go b/internal/service/networkmanager/ignore/site_data_source_test.go similarity index 100% rename from internal/service/networkmanager/site_data_source_test.go rename to internal/service/networkmanager/ignore/site_data_source_test.go diff --git a/internal/service/networkmanager/site_test.go b/internal/service/networkmanager/ignore/site_test.go similarity index 100% rename from internal/service/networkmanager/site_test.go rename to internal/service/networkmanager/ignore/site_test.go diff --git a/internal/service/networkmanager/transit_gateway_registration.go b/internal/service/networkmanager/ignore/transit_gateway_registration.go similarity index 100% rename from internal/service/networkmanager/transit_gateway_registration.go rename to internal/service/networkmanager/ignore/transit_gateway_registration.go diff --git a/internal/service/networkmanager/transit_gateway_registration_test.go b/internal/service/networkmanager/ignore/transit_gateway_registration_test.go similarity index 100% rename from internal/service/networkmanager/transit_gateway_registration_test.go rename to internal/service/networkmanager/ignore/transit_gateway_registration_test.go From 8f6221816978b1e19e373dc603647d0e59fd6e2e Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 13:58:03 -0500 Subject: [PATCH 040/229] Run 'make fmt'. --- internal/service/networkmanager/ignore/device.go | 2 +- internal/service/networkmanager/ignore/site.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/networkmanager/ignore/device.go b/internal/service/networkmanager/ignore/device.go index 0c27c72c7cc..7e6ce8214d8 100644 --- a/internal/service/networkmanager/ignore/device.go +++ b/internal/service/networkmanager/ignore/device.go @@ -12,8 +12,8 @@ import ( "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/terraform-providers/terraform-provider-aws/internal/keyvaluetags" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/terraform-providers/terraform-provider-aws/internal/keyvaluetags" ) func ResourceDevice() *schema.Resource { diff --git a/internal/service/networkmanager/ignore/site.go b/internal/service/networkmanager/ignore/site.go index dc41f5ee148..2188568d89a 100644 --- a/internal/service/networkmanager/ignore/site.go +++ b/internal/service/networkmanager/ignore/site.go @@ -12,8 +12,8 @@ import ( "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/terraform-providers/terraform-provider-aws/internal/keyvaluetags" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/terraform-providers/terraform-provider-aws/internal/keyvaluetags" ) func ResourceSite() *schema.Resource { From 661d5d1063ad06e62aa0b15a1afa8b1b803526c9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 13:58:39 -0500 Subject: [PATCH 041/229] Documentation subcategory is 'Network Manager'. --- website/allowed-subcategories.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/allowed-subcategories.txt b/website/allowed-subcategories.txt index 8b3f2980836..a28c1f65fe7 100644 --- a/website/allowed-subcategories.txt +++ b/website/allowed-subcategories.txt @@ -106,6 +106,7 @@ MemoryDB Managed Workflows for Apache Airflow (MWAA) Neptune Network Firewall +Network Manager OpsWorks Organizations Outposts @@ -147,7 +148,6 @@ Storage Gateway Synthetics Timestream Write Transfer -Transit Gateway Network Manager VPC WAF Regional WAF From f722ea1f95255293d467370fb34171d1babfc131 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 13:59:11 -0500 Subject: [PATCH 042/229] 'IgnoreAws' -> 'IgnoreAWS'. --- docs/contributing/contribution-checklists.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/contributing/contribution-checklists.md b/docs/contributing/contribution-checklists.md index 40af5794e1d..b198cfc9f3a 100644 --- a/docs/contributing/contribution-checklists.md +++ b/docs/contributing/contribution-checklists.md @@ -332,7 +332,7 @@ More details about this code generation, including fixes for potential error mes input := &eks.CreateClusterInput{ /* ... other configuration ... */ - Tags: Tags(tags.IgnoreAws()), + Tags: Tags(tags.IgnoreAWS()), } ``` @@ -348,7 +348,7 @@ More details about this code generation, including fixes for potential error mes } if len(tags) > 0 { - input.Tags = Tags(tags.IgnoreAws()) + input.Tags = Tags(tags.IgnoreAWS()) } ``` @@ -388,7 +388,7 @@ More details about this code generation, including fixes for potential error mes /* ... other d.Set(...) logic ... */ - tags := keyvaluetags.EksKeyValueTags(cluster.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + tags := keyvaluetags.EksKeyValueTags(cluster.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { return fmt.Errorf("error setting tags: %w", err) @@ -414,7 +414,7 @@ More details about this code generation, including fixes for potential error mes return fmt.Errorf("error listing tags for resource (%s): %w", arn, err) } - tags = tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig) + tags = tags.IgnoreAWS().IgnoreConfig(ignoreTagsConfig) if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { return fmt.Errorf("error setting tags: %w", err) @@ -595,7 +595,7 @@ filters := namevaluesfilters.New(map[string]string{ "internet-gateway-id": d.Get("internet_gateway_id").(string), }) // Add filters based on keyvalue tags (N.B. Not applicable to all AWS services that support filtering) -filters.Add(namevaluesfilters.Ec2Tags(keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map())) +filters.Add(namevaluesfilters.Ec2Tags(keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAWS().IgnoreConfig(ignoreTagsConfig).Map())) // Add filters based on the custom filtering "filter" attribute. filters.Add(d.Get("filter").(*schema.Set)) From 123ac24867febea14ab2a03281bafd5083e5a123 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 13:59:57 -0500 Subject: [PATCH 043/229] r/aws_networkmanager_global_network: Modernize resource. --- .../service/networkmanager/global_network.go | 335 ++++++++++-------- .../r/networkmanager_global_network.markdown | 5 +- 2 files changed, 183 insertions(+), 157 deletions(-) diff --git a/internal/service/networkmanager/global_network.go b/internal/service/networkmanager/global_network.go index 6bce3707855..f7fd947a805 100644 --- a/internal/service/networkmanager/global_network.go +++ b/internal/service/networkmanager/global_network.go @@ -1,288 +1,313 @@ package networkmanager import ( - "fmt" + "context" "log" "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/terraform-providers/terraform-provider-aws/internal/keyvaluetags" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/internal/verify" ) func ResourceGlobalNetwork() *schema.Resource { return &schema.Resource{ - Create: ResourceGlobalNetworkCreate, - Read: ResourceGlobalNetworkRead, - Update: ResourceGlobalNetworkUpdate, - Delete: ResourceGlobalNetworkDelete, + CreateWithoutTimeout: resourceGlobalNetworkCreate, + ReadWithoutTimeout: resourceGlobalNetworkRead, + UpdateWithoutTimeout: resourceGlobalNetworkUpdate, + DeleteWithoutTimeout: resourceGlobalNetworkDelete, + Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, + CustomizeDiff: verify.SetTagsDiff, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Update: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + Schema: map[string]*schema.Schema{ "arn": { Type: schema.TypeString, Computed: true, }, "description": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 256), }, - "tags": tagsSchema(), + "tags": tftags.TagsSchema(), + "tags_all": tftags.TagsSchemaComputed(), }, } } -func ResourceGlobalNetworkCreate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn +func resourceGlobalNetworkCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{}))) - input := &networkmanager.CreateGlobalNetworkInput{ - Description: aws.String(d.Get("description").(string)), - Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().NetworkmanagerTags(), - } + input := &networkmanager.CreateGlobalNetworkInput{} if v, ok := d.GetOk("description"); ok { input.Description = aws.String(v.(string)) } - log.Printf("[DEBUG] Creating Network Manager Global Network: %s", input) - var output *networkmanager.CreateGlobalNetworkOutput - err := resource.Retry(1*time.Minute, func() *resource.RetryError { - var err error - output, err = conn.CreateGlobalNetwork(input) - if err != nil { - if tfawserr.ErrMessageContains(err, "ValidationException", "Resource already exists with ID") { - return resource.RetryableError(err) - } - return resource.NonRetryableError(err) - } - return nil - }) - if tfresource.TimedOut(err) { - output, err = conn.CreateGlobalNetwork(input) + if len(tags) > 0 { + input.Tags = Tags(tags.IgnoreAWS()) } + + log.Printf("[DEBUG] Creating Network Manager Global Network: %s", input) + output, err := conn.CreateGlobalNetworkWithContext(ctx, input) + if err != nil { - return fmt.Errorf("error creating Network Manager Global Network: %s", err) + return diag.Errorf("error creating Network Manager Global Network: %s", err) } d.SetId(aws.StringValue(output.GlobalNetwork.GlobalNetworkId)) - stateConf := &resource.StateChangeConf{ - Pending: []string{networkmanager.GlobalNetworkStatePending}, - Target: []string{networkmanager.GlobalNetworkStateAvailable}, - Refresh: networkmanagerGlobalNetworkRefreshFunc(conn, aws.StringValue(output.GlobalNetwork.GlobalNetworkId)), - Timeout: 10 * time.Minute, - } - - _, err = stateConf.WaitForState() - if err != nil { - return fmt.Errorf("error waiting for networkmanager Global Network (%s) availability: %s", d.Id(), err) + if _, err := waitGlobalNetworkCreated(ctx, conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { + return diag.Errorf("error waiting for Network Manager Global Network (%s) create: %s", d.Id(), err) } - return ResourceGlobalNetworkRead(d, meta) + return resourceGlobalNetworkRead(ctx, d, meta) } -func ResourceGlobalNetworkRead(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn - ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig +func resourceGlobalNetworkRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig - globalNetwork, err := networkmanagerDescribeGlobalNetwork(conn, d.Id()) + globalNetwork, err := FindGlobalNetworkByID(ctx, conn, d.Id()) - if tfawserr.ErrCodeEquals(err, "InvalidGlobalNetworkID.NotFound", "") { - log.Printf("[WARN] networkmanager Global Network (%s) not found, removing from state", d.Id()) + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Network Manager Global Network %s not found, removing from state", d.Id()) d.SetId("") return nil } if err != nil { - return fmt.Errorf("error reading networkmanager Global Network: %s", err) - } - - if globalNetwork == nil { - log.Printf("[WARN] networkmanager Global Network (%s) not found, removing from state", d.Id()) - d.SetId("") - return nil - } - - if aws.StringValue(globalNetwork.State) == networkmanager.GlobalNetworkStateDeleting { - log.Printf("[WARN] networkmanager Global Network (%s) in deleted state (%s), removing from state", d.Id(), aws.StringValue(globalNetwork.State)) - d.SetId("") - return nil + return diag.Errorf("error reading Network Manager Global Network (%s): %s", d.Id(), err) } d.Set("arn", globalNetwork.GlobalNetworkArn) d.Set("description", globalNetwork.Description) - if err := d.Set("tags", keyvaluetags.NetworkmanagerKeyValueTags(globalNetwork.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %s", err) + tags := KeyValueTags(globalNetwork.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return diag.Errorf("error setting tags: %s", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return diag.Errorf("error setting tags_all: %s", err) } return nil } -func ResourceGlobalNetworkUpdate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn +func resourceGlobalNetworkUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn if d.HasChange("description") { - request := &networkmanager.UpdateGlobalNetworkInput{ + input := &networkmanager.UpdateGlobalNetworkInput{ Description: aws.String(d.Get("description").(string)), GlobalNetworkId: aws.String(d.Id()), } - _, err := conn.UpdateGlobalNetwork(request) + log.Printf("[DEBUG] Updating Network Manager Global Network: %s", input) + _, err := conn.UpdateGlobalNetworkWithContext(ctx, input) + if err != nil { - return fmt.Errorf("Failure updating Network Manager Global Network description: %s", err) + return diag.Errorf("error updating Network Manager Global Network (%s): %s", d.Id(), err) + } + + if _, err := waitGlobalNetworkUpdated(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate)); err != nil { + return diag.Errorf("error waiting for Network Manager Global Network (%s) update: %s", d.Id(), err) } } - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") - if err := keyvaluetags.NetworkmanagerUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { - return fmt.Errorf("error updating networkmanager Global Network (%s) tags: %s", d.Id(), err) + if err := UpdateTags(conn, d.Id(), o, n); err != nil { + return diag.Errorf("error updating Network Manager Global Network (%s) tags: %s", d.Id(), err) } } + return resourceGlobalNetworkRead(ctx, d, meta) +} + +func resourceGlobalNetworkDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + log.Printf("[DEBUG] Deleting Network Manager Global Network: %s", d.Id()) + _, err := tfresource.RetryWhenAWSErrCodeEqualsContext(ctx, globalNetworkValidationException, func() (interface{}, error) { + return conn.DeleteGlobalNetworkWithContext(ctx, &networkmanager.DeleteGlobalNetworkInput{ + GlobalNetworkId: aws.String(d.Id()), + }) + }, networkmanager.ErrCodeValidationException) + + if tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeResourceNotFoundException) { + return nil + } + + if err != nil { + return diag.Errorf("error deleting Network Manager Global Network (%s): %s", d.Id(), err) + } + + if _, err := waitGlobalNetworkDeleted(ctx, conn, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil { + return diag.Errorf("error waiting for Network Manager Global Network (%s) delete: %s", d.Id(), err) + } + return nil } -func ResourceGlobalNetworkDelete(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn +func FindGlobalNetwork(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.DescribeGlobalNetworksInput) (*networkmanager.GlobalNetwork, error) { + output, err := FindGlobalNetworks(ctx, conn, input) - input := &networkmanager.DeleteGlobalNetworkInput{ - GlobalNetworkId: aws.String(d.Id()), + if err != nil { + return nil, err } - log.Printf("[DEBUG] Deleting networkmanager Global Network (%s): %s", d.Id(), input) - err := resource.Retry(2*time.Minute, func() *resource.RetryError { - _, err := conn.DeleteGlobalNetwork(input) + if len(output) == 0 || output[0] == nil { + return nil, tfresource.NewEmptyResultError(input) + } - if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Transit Gateway Registrations") { - return resource.RetryableError(err) - } + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } - if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Customer Gateway Associations") { - return resource.RetryableError(err) - } + return output[0], nil +} - if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Device") { - return resource.RetryableError(err) - } +func FindGlobalNetworks(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.DescribeGlobalNetworksInput) ([]*networkmanager.GlobalNetwork, error) { + var output []*networkmanager.GlobalNetwork - if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Link") { - return resource.RetryableError(err) + err := conn.DescribeGlobalNetworksPagesWithContext(ctx, input, func(page *networkmanager.DescribeGlobalNetworksOutput, lastPage bool) bool { + if page == nil { + return !lastPage } - if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Site") { - return resource.RetryableError(err) - } + for _, v := range page.GlobalNetworks { + if v == nil { + continue + } - if err != nil { - return resource.NonRetryableError(err) + output = append(output, v) } - return nil + return !lastPage }) - if tfresource.TimedOut(err) { - _, err = conn.DeleteGlobalNetwork(input) + if err != nil { + return nil, err } - if tfawserr.ErrCodeEquals(err, "InvalidGlobalNetworkID.NotFound", "") { - return nil + return output, nil +} + +func FindGlobalNetworkByID(ctx context.Context, conn *networkmanager.NetworkManager, id string) (*networkmanager.GlobalNetwork, error) { + input := &networkmanager.DescribeGlobalNetworksInput{ + GlobalNetworkIds: aws.StringSlice([]string{id}), } + output, err := FindGlobalNetwork(ctx, conn, input) + if err != nil { - return fmt.Errorf("error deleting networkmanager Global Network: %s", err) + return nil, err } - if err := waitForGlobalNetworkDeletion(conn, d.Id()); err != nil { - return fmt.Errorf("error waiting for networkmanager Global Network (%s) deletion: %s", d.Id(), err) + // Eventual consistency check. + if aws.StringValue(output.GlobalNetworkId) != id { + return nil, &resource.NotFoundError{ + LastRequest: input, + } } - return nil + return output, nil } -func networkmanagerGlobalNetworkRefreshFunc(conn *networkmanager.NetworkManager, globalNetworkID string) resource.StateRefreshFunc { +func statusGlobalNetworkState(ctx context.Context, conn *networkmanager.NetworkManager, id string) resource.StateRefreshFunc { return func() (interface{}, string, error) { - globalNetwork, err := networkmanagerDescribeGlobalNetwork(conn, globalNetworkID) + output, err := FindGlobalNetworkByID(ctx, conn, id) - if tfawserr.ErrCodeEquals(err, "InvalidGlobalNetworkID.NotFound", "") { - return nil, "DELETED", nil + if tfresource.NotFound(err) { + return nil, "", nil } if err != nil { - return nil, "", fmt.Errorf("error reading Global Network (%s): %s", globalNetworkID, err) + return nil, "", err } - if globalNetwork == nil { - return nil, "DELETED", nil - } - - return globalNetwork, aws.StringValue(globalNetwork.State), nil + return output, string(*output.State), nil } } -func networkmanagerDescribeGlobalNetwork(conn *networkmanager.NetworkManager, globalNetworkID string) (*networkmanager.GlobalNetwork, error) { - input := &networkmanager.DescribeGlobalNetworksInput{ - GlobalNetworkIds: []*string{aws.String(globalNetworkID)}, +func waitGlobalNetworkCreated(ctx context.Context, conn *networkmanager.NetworkManager, id string, timeout time.Duration) (*networkmanager.GlobalNetwork, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.GlobalNetworkStatePending}, + Target: []string{networkmanager.GlobalNetworkStateAvailable}, + Timeout: timeout, + Refresh: statusGlobalNetworkState(ctx, conn, id), } - log.Printf("[DEBUG] Reading Global Network (%s): %s", globalNetworkID, input) - for { - output, err := conn.DescribeGlobalNetworks(input) - - if err != nil { - return nil, err - } + outputRaw, err := stateConf.WaitForStateContext(ctx) - if output == nil || len(output.GlobalNetworks) == 0 { - return nil, nil - } + if output, ok := outputRaw.(*networkmanager.GlobalNetwork); ok { + return output, err + } - for _, globalNetwork := range output.GlobalNetworks { - if globalNetwork == nil { - continue - } + return nil, err +} - if aws.StringValue(globalNetwork.GlobalNetworkId) == globalNetworkID { - return globalNetwork, nil - } - } +func waitGlobalNetworkDeleted(ctx context.Context, conn *networkmanager.NetworkManager, id string, timeout time.Duration) (*networkmanager.GlobalNetwork, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.GlobalNetworkStateDeleting}, + Target: []string{}, + Timeout: timeout, + Refresh: statusGlobalNetworkState(ctx, conn, id), + NotFoundChecks: 1, + } - if aws.StringValue(output.NextToken) == "" { - break - } + outputRaw, err := stateConf.WaitForStateContext(ctx) - input.NextToken = output.NextToken + if output, ok := outputRaw.(*networkmanager.GlobalNetwork); ok { + return output, err } - return nil, nil + return nil, err } -func waitForGlobalNetworkDeletion(conn *networkmanager.NetworkManager, globalNetworkID string) error { +func waitGlobalNetworkUpdated(ctx context.Context, conn *networkmanager.NetworkManager, id string, timeout time.Duration) (*networkmanager.GlobalNetwork, error) { stateConf := &resource.StateChangeConf{ - Pending: []string{ - networkmanager.GlobalNetworkStateAvailable, - networkmanager.GlobalNetworkStateDeleting, - }, - Target: []string{""}, - Refresh: networkmanagerGlobalNetworkRefreshFunc(conn, globalNetworkID), - Timeout: 10 * time.Minute, - NotFoundChecks: 1, + Pending: []string{networkmanager.GlobalNetworkStateUpdating}, + Target: []string{networkmanager.GlobalNetworkStateAvailable}, + Timeout: timeout, + Refresh: statusGlobalNetworkState(ctx, conn, id), } - log.Printf("[DEBUG] Waiting for Global Network (%s) deletion", globalNetworkID) - _, err := stateConf.WaitForState() + outputRaw, err := stateConf.WaitForStateContext(ctx) - if tfresource.NotFound(err) { - return nil + if output, ok := outputRaw.(*networkmanager.GlobalNetwork); ok { + return output, err } - return err + return nil, err } + +const ( + globalNetworkValidationException = 2 * time.Minute +) diff --git a/website/docs/r/networkmanager_global_network.markdown b/website/docs/r/networkmanager_global_network.markdown index c611f6f2067..d5ae323e01e 100644 --- a/website/docs/r/networkmanager_global_network.markdown +++ b/website/docs/r/networkmanager_global_network.markdown @@ -1,5 +1,5 @@ --- -subcategory: "Transit Gateway Network Manager" +subcategory: "Network Manager" layout: "aws" page_title: "AWS: aws_networkmanager_global_network" description: |- @@ -23,13 +23,14 @@ resource "aws_networkmanager_global_network" "example" { The following arguments are supported: * `description` - (Optional) Description of the Global Network. -* `tags` - (Optional) Key-value tags for the Global Network. +* `tags` - (Optional) Key-value tags for the Global Network. If configured with a provider [`default_tags` configuration block](https://www.terraform.io/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ## Attributes Reference In addition to all arguments above, the following attributes are exported: * `arn` - Global Network Amazon Resource Name (ARN) +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](https://www.terraform.io/docs/providers/aws/index.html#default_tags-configuration-block). ## Import From d4b9e468aa25e956e85cafdc6029ecb416e94c4a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 14:21:50 -0500 Subject: [PATCH 044/229] Start work on Global Network acceptance tests. --- .../service/networkmanager/{ignore => }/global_network_test.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename internal/service/networkmanager/{ignore => }/global_network_test.go (100%) diff --git a/internal/service/networkmanager/ignore/global_network_test.go b/internal/service/networkmanager/global_network_test.go similarity index 100% rename from internal/service/networkmanager/ignore/global_network_test.go rename to internal/service/networkmanager/global_network_test.go From 8b947e9cc760ba8389351332691fd520ac8f4b5e Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 14:51:20 -0500 Subject: [PATCH 045/229] Sweep Global Networks. --- internal/service/networkmanager/sweep.go | 68 ++++++++++++++++++++++++ internal/sweep/sweep_test.go | 1 + 2 files changed, 69 insertions(+) create mode 100644 internal/service/networkmanager/sweep.go diff --git a/internal/service/networkmanager/sweep.go b/internal/service/networkmanager/sweep.go new file mode 100644 index 00000000000..e86428316de --- /dev/null +++ b/internal/service/networkmanager/sweep.go @@ -0,0 +1,68 @@ +//go:build sweep +// +build sweep + +package networkmanager + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/sweep" +) + +func init() { + resource.AddTestSweepers("aws_networkmanager_global_network", &resource.Sweeper{ + Name: "aws_networkmanager_global_network", + F: sweepGlobalNetworks, + // Dependencies: []string{ + // "aws_networkmanager_site", + // }, + }) +} + +func sweepGlobalNetworks(region string) error { + client, err := sweep.SharedRegionalSweepClient(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*conns.AWSClient).NetworkManagerConn + input := &networkmanager.DescribeGlobalNetworksInput{} + sweepResources := make([]*sweep.SweepResource, 0) + + err = conn.DescribeGlobalNetworksPages(input, func(page *networkmanager.DescribeGlobalNetworksOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.GlobalNetworks { + r := ResourceGlobalNetwork() + d := r.Data(nil) + d.SetId(aws.StringValue(v.GlobalNetworkId)) + + sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) + } + + return !lastPage + }) + + if sweep.SkipSweepError(err) { + log.Printf("[WARN] Skipping Network Manager Global Network sweep for %s: %s", region, err) + return nil + } + + if err != nil { + return fmt.Errorf("error listing Network Manager Global Networks (%s): %w", region, err) + } + + err = sweep.SweepOrchestrator(sweepResources) + + if err != nil { + return fmt.Errorf("error sweeping Network Manager Global Networks (%s): %w", region, err) + } + + return nil +} diff --git a/internal/sweep/sweep_test.go b/internal/sweep/sweep_test.go index ea81c32edb2..2204d46303b 100644 --- a/internal/sweep/sweep_test.go +++ b/internal/sweep/sweep_test.go @@ -82,6 +82,7 @@ import ( _ "github.com/hashicorp/terraform-provider-aws/internal/service/mwaa" _ "github.com/hashicorp/terraform-provider-aws/internal/service/neptune" _ "github.com/hashicorp/terraform-provider-aws/internal/service/networkfirewall" + _ "github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager" _ "github.com/hashicorp/terraform-provider-aws/internal/service/opsworks" _ "github.com/hashicorp/terraform-provider-aws/internal/service/pinpoint" _ "github.com/hashicorp/terraform-provider-aws/internal/service/qldb" From dc0c4b17eb49ac68a834a6fba7d3f754444bbe41 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 15:01:01 -0500 Subject: [PATCH 046/229] Add 'aws_networkmanager_global_network'. --- internal/provider/provider.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index bf20163f0c7..6dcc287a653 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -118,6 +118,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/service/mwaa" "github.com/hashicorp/terraform-provider-aws/internal/service/neptune" "github.com/hashicorp/terraform-provider-aws/internal/service/networkfirewall" + "github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager" "github.com/hashicorp/terraform-provider-aws/internal/service/opsworks" "github.com/hashicorp/terraform-provider-aws/internal/service/organizations" "github.com/hashicorp/terraform-provider-aws/internal/service/outposts" @@ -1576,6 +1577,8 @@ func Provider() *schema.Provider { "aws_networkfirewall_resource_policy": networkfirewall.ResourceResourcePolicy(), "aws_networkfirewall_rule_group": networkfirewall.ResourceRuleGroup(), + "aws_networkmanager_global_network": networkmanager.ResourceGlobalNetwork(), + "aws_opsworks_application": opsworks.ResourceApplication(), "aws_opsworks_custom_layer": opsworks.ResourceCustomLayer(), "aws_opsworks_ecs_cluster_layer": opsworks.ResourceECSClusterLayer(), From 8442d4e3677e43a53d0a87441b2570a7af8d67f4 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 15:18:32 -0500 Subject: [PATCH 047/229] Pass ARN not ID when updating tags. --- internal/service/networkmanager/global_network.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/networkmanager/global_network.go b/internal/service/networkmanager/global_network.go index f7fd947a805..04c883379d4 100644 --- a/internal/service/networkmanager/global_network.go +++ b/internal/service/networkmanager/global_network.go @@ -142,7 +142,7 @@ func resourceGlobalNetworkUpdate(ctx context.Context, d *schema.ResourceData, me if d.HasChange("tags_all") { o, n := d.GetChange("tags_all") - if err := UpdateTags(conn, d.Id(), o, n); err != nil { + if err := UpdateTags(conn, d.Get("arn").(string), o, n); err != nil { return diag.Errorf("error updating Network Manager Global Network (%s) tags: %s", d.Id(), err) } } From 69b6cee2a4b56cb30aa899700768bf91986f6a47 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 15:18:41 -0500 Subject: [PATCH 048/229] r/aws_networkmanager_global_network: Acceptance tests passing. Acceptance test output: % TF_ACC=1 go test ./internal/service/networkmanager -v -count 1 -parallel 20 -run='TestAccNetworkManagerGlobalNetwork_' -timeout 180m === RUN TestAccNetworkManagerGlobalNetwork_basic === PAUSE TestAccNetworkManagerGlobalNetwork_basic === RUN TestAccNetworkManagerGlobalNetwork_disappears === PAUSE TestAccNetworkManagerGlobalNetwork_disappears === RUN TestAccNetworkManagerGlobalNetwork_tags === PAUSE TestAccNetworkManagerGlobalNetwork_tags === RUN TestAccNetworkManagerGlobalNetwork_description === PAUSE TestAccNetworkManagerGlobalNetwork_description === CONT TestAccNetworkManagerGlobalNetwork_basic === CONT TestAccNetworkManagerGlobalNetwork_tags === CONT TestAccNetworkManagerGlobalNetwork_disappears === CONT TestAccNetworkManagerGlobalNetwork_description --- PASS: TestAccNetworkManagerGlobalNetwork_disappears (150.82s) --- PASS: TestAccNetworkManagerGlobalNetwork_basic (161.93s) --- PASS: TestAccNetworkManagerGlobalNetwork_description (187.58s) --- PASS: TestAccNetworkManagerGlobalNetwork_tags (594.81s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 602.409s --- .../networkmanager/global_network_test.go | 237 ++++++++---------- 1 file changed, 105 insertions(+), 132 deletions(-) diff --git a/internal/service/networkmanager/global_network_test.go b/internal/service/networkmanager/global_network_test.go index 463cc2c2509..6685cebf065 100644 --- a/internal/service/networkmanager/global_network_test.go +++ b/internal/service/networkmanager/global_network_test.go @@ -1,93 +1,36 @@ -package networkmanager +package networkmanager_test import ( + "context" "fmt" - "log" "regexp" "testing" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" - "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tfnetworkmanager "github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -func init() { - resource.AddTestSweepers("aws_networkmanager_global_network", &resource.Sweeper{ - Name: "aws_networkmanager_global_network", - F: testSweepGlobalNetwork, - }) -} - -func testSweepGlobalNetwork(region string) error { - client, err := sharedClientForRegion(region) - if err != nil { - return fmt.Errorf("error getting client: %s", err) - } - conn := client.(*AWSClient).networkmanagerconn - input := &networkmanager.DescribeGlobalNetworksInput{} - var sweeperErrs *multierror.Error - - err = conn.DescribeGlobalNetworksPages(input, - func(page *networkmanager.DescribeGlobalNetworksOutput, lastPage bool) bool { - for _, globalNetwork := range page.GlobalNetworks { - input := &networkmanager.DeleteGlobalNetworkInput{ - GlobalNetworkId: globalNetwork.GlobalNetworkId, - } - id := aws.StringValue(globalNetwork.GlobalNetworkId) - - log.Printf("[INFO] Deleting Network Manager Global Network: %s", id) - _, err := conn.DeleteGlobalNetwork(input) - - if tfawserr.ErrCodeEquals(err, "InvalidGlobalNetworkID.NotFound", "") { - continue - } - - if err != nil { - sweeperErr := fmt.Errorf("failed to delete Network Manager Global Network %s: %s", id, err) - log.Printf("[ERROR] %s", sweeperErr) - sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) - continue - } - - if err := waitForGlobalNetworkDeletion(conn, id); err != nil { - sweeperErr := fmt.Errorf("error waiting for Network Manager Global Network (%s) deletion: %s", id, err) - log.Printf("[ERROR] %s", sweeperErr) - sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) - continue - } - } - return !lastPage - }) - if testSweepSkipSweepError(err) { - log.Printf("[WARN] Skipping Network Manager Global Network sweep for %s: %s", region, err) - return nil - } - - if err != nil { - return fmt.Errorf("Error retrieving Network Manager Global Networks: %s", err) - } - - return sweeperErrs.ErrorOrNil() -} - -func TestAccGlobalNetwork_basic(t *testing.T) { +func TestAccNetworkManagerGlobalNetwork_basic(t *testing.T) { resourceName := "aws_networkmanager_global_network.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAwsGlobalNetworkDestroy, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckGlobalNetworkDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalNetworkConfig("test"), + Config: testAccGlobalNetworkConfig(), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsGlobalNetworkExists(resourceName), - testAccMatchResourceAttrGlobalARN(resourceName, "arn", "networkmanager", regexp.MustCompile(`global-network/global-network-.+`)), - resource.TestCheckResourceAttr(resourceName, "description", "test"), + testAccCheckGlobalNetworkExists(resourceName), + acctest.MatchResourceAttrGlobalARN(resourceName, "arn", "networkmanager", regexp.MustCompile(`global-network/global-network-.+`)), + resource.TestCheckResourceAttr(resourceName, "description", ""), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, { @@ -95,32 +38,44 @@ func TestAccGlobalNetwork_basic(t *testing.T) { ImportState: true, ImportStateVerify: true, }, + }, + }) +} + +func TestAccNetworkManagerGlobalNetwork_disappears(t *testing.T) { + resourceName := "aws_networkmanager_global_network.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckGlobalNetworkDestroy, + Steps: []resource.TestStep{ { - Config: testAccGlobalNetworkConfig_Update("test updated"), + Config: testAccGlobalNetworkConfig(), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsGlobalNetworkExists(resourceName), - testAccMatchResourceAttrGlobalARN(resourceName, "arn", "networkmanager", regexp.MustCompile(`global-network/global-network-.+`)), - resource.TestCheckResourceAttr(resourceName, "description", "test updated"), + testAccCheckGlobalNetworkExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfnetworkmanager.ResourceGlobalNetwork(), resourceName), ), + ExpectNonEmptyPlan: true, }, }, }) } -func TestAccGlobalNetwork_tags(t *testing.T) { +func TestAccNetworkManagerGlobalNetwork_tags(t *testing.T) { resourceName := "aws_networkmanager_global_network.test" - description := "test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAwsGlobalNetworkDestroy, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckGlobalNetworkDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalNetworkConfigTags1(description, "key1", "value1"), + Config: testAccGlobalNetworkConfigTags1("key1", "value1"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsGlobalNetworkExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "description", "test"), + testAccCheckGlobalNetworkExists(resourceName), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), ), @@ -131,20 +86,18 @@ func TestAccGlobalNetwork_tags(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccGlobalNetworkConfigTags2(description, "key1", "value1updated", "key2", "value2"), + Config: testAccGlobalNetworkConfigTags2("key1", "value1updated", "key2", "value2"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsGlobalNetworkExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "description", "test"), + testAccCheckGlobalNetworkExists(resourceName), resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), ), }, { - Config: testAccGlobalNetworkConfigTags1(description, "key2", "value2"), + Config: testAccGlobalNetworkConfigTags1("key2", "value2"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsGlobalNetworkExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "description", "test"), + testAccCheckGlobalNetworkExists(resourceName), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), ), @@ -153,96 +106,116 @@ func TestAccGlobalNetwork_tags(t *testing.T) { }) } -func testAccCheckAwsGlobalNetworkDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn +func TestAccNetworkManagerGlobalNetwork_description(t *testing.T) { + resourceName := "aws_networkmanager_global_network.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckGlobalNetworkDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGlobalNetworkDescriptionConfig("description1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGlobalNetworkExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "description1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGlobalNetworkDescriptionConfig("description2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGlobalNetworkExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "description2"), + ), + }, + }, + }) +} + +func testAccCheckGlobalNetworkDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_networkmanager_global_network" { continue } - globalNetwork, err := networkmanagerDescribeGlobalNetwork(conn, rs.Primary.ID) - if err != nil { - if tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeResourceNotFoundException, "") { - return nil - } - return err - } + _, err := tfnetworkmanager.FindGlobalNetworkByID(context.TODO(), conn, rs.Primary.ID) - if globalNetwork == nil { + if tfresource.NotFound(err) { continue } - return fmt.Errorf("Expected Global Network to be destroyed, %s found", rs.Primary.ID) + if err != nil { + return err + } + + return fmt.Errorf("Network Manager Global Network %s still exists", rs.Primary.ID) } return nil } -func testAccCheckAwsGlobalNetworkExists(name string) resource.TestCheckFunc { +func testAccCheckGlobalNetworkExists(n string) resource.TestCheckFunc { return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[name] + rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not found: %s", name) + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No Network Manager Global Network ID is set") } - conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn - globalNetwork, err := networkmanagerDescribeGlobalNetwork(conn, rs.Primary.ID) + _, err := tfnetworkmanager.FindGlobalNetworkByID(context.TODO(), conn, rs.Primary.ID) if err != nil { return err } - if globalNetwork == nil { - return fmt.Errorf("Network Manager Global Network not found") - } - - if aws.StringValue(globalNetwork.State) != networkmanager.GlobalNetworkStateAvailable && aws.StringValue(globalNetwork.State) != networkmanager.GlobalNetworkStatePending { - return fmt.Errorf("Network Manager Global Network (%s) exists in (%s) state", rs.Primary.ID, aws.StringValue(globalNetwork.State)) - } - - return err + return nil } } -func testAccGlobalNetworkConfig(description string) string { - return fmt.Sprintf(` -resource "aws_networkmanager_global_network" "test" { - description = %q -} -`, description) +func testAccGlobalNetworkConfig() string { + return ` +resource "aws_networkmanager_global_network" "test" {} +` } -func testAccGlobalNetworkConfigTags1(description, tagKey1, tagValue1 string) string { +func testAccGlobalNetworkConfigTags1(tagKey1, tagValue1 string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { - description = %q - tags = { - %q = %q + %[1]q = %[2]q } } -`, description, tagKey1, tagValue1) +`, tagKey1, tagValue1) } -func testAccGlobalNetworkConfigTags2(description, tagKey1, tagValue1, tagKey2, tagValue2 string) string { +func testAccGlobalNetworkConfigTags2(tagKey1, tagValue1, tagKey2, tagValue2 string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { - description = %q - tags = { - %q = %q - %q = %q + %[1]q = %[2]q + %[3]q = %[4]q } } -`, description, tagKey1, tagValue1, tagKey2, tagValue2) +`, tagKey1, tagValue1, tagKey2, tagValue2) } -func testAccGlobalNetworkConfig_Update(description string) string { +func testAccGlobalNetworkDescriptionConfig(description string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { - description = %q + description = %[1]q } `, description) } From 3542df75265234e953ba929edf6ae3e4c1759a0b Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 15:33:22 -0500 Subject: [PATCH 049/229] Start work on Global Network data source. --- .../networkmanager/{ignore => }/global_network_data_source.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename internal/service/networkmanager/{ignore => }/global_network_data_source.go (100%) diff --git a/internal/service/networkmanager/ignore/global_network_data_source.go b/internal/service/networkmanager/global_network_data_source.go similarity index 100% rename from internal/service/networkmanager/ignore/global_network_data_source.go rename to internal/service/networkmanager/global_network_data_source.go From 95d57a091703fbcc82bdd0b4e2c027bc134dc205 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 15:44:23 -0500 Subject: [PATCH 050/229] d/aws_networkmanager_global_network: Modernize. --- internal/provider/provider.go | 2 + .../global_network_data_source.go | 78 +++++-------------- .../d/networkmanager_global_network.markdown | 10 +-- 3 files changed, 25 insertions(+), 65 deletions(-) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 6dcc287a653..b625ecd864c 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -713,6 +713,8 @@ func Provider() *schema.Provider { "aws_neptune_engine_version": neptune.DataSourceEngineVersion(), "aws_neptune_orderable_db_instance": neptune.DataSourceOrderableDBInstance(), + "aws_networkmanager_global_network": networkmanager.DataSourceGlobalNetwork(), + "aws_organizations_delegated_administrators": organizations.DataSourceDelegatedAdministrators(), "aws_organizations_delegated_services": organizations.DataSourceDelegatedServices(), "aws_organizations_organization": organizations.DataSourceOrganization(), diff --git a/internal/service/networkmanager/global_network_data_source.go b/internal/service/networkmanager/global_network_data_source.go index 0fcdbc40602..8bdee16dbea 100644 --- a/internal/service/networkmanager/global_network_data_source.go +++ b/internal/service/networkmanager/global_network_data_source.go @@ -1,19 +1,17 @@ package networkmanager import ( - "errors" - "fmt" - "log" + "context" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" ) func DataSourceGlobalNetwork() *schema.Resource { return &schema.Resource{ - Read: DataSourceGlobalNetworkRead, + ReadWithoutTimeout: dataSourceGlobalNetworkRead, Schema: map[string]*schema.Schema{ "arn": { @@ -24,72 +22,34 @@ func DataSourceGlobalNetwork() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "id": { + "global_network_id": { Type: schema.TypeString, - Optional: true, + Required: true, }, - "tags": tagsSchemaComputed(), + "tags": tftags.TagsSchemaComputed(), }, } } -func DataSourceGlobalNetworkRead(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn - ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig +func dataSourceGlobalNetworkRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig - input := &networkmanager.DescribeGlobalNetworksInput{} - - if v, ok := d.GetOk("id"); ok { - input.GlobalNetworkIds = aws.StringSlice([]string{v.(string)}) - } - - log.Printf("[DEBUG] Reading Network Manager Global Network: %s", input) - output, err := conn.DescribeGlobalNetworks(input) + globalNetworkID := d.Get("global_network_id").(string) + globalNetwork, err := FindGlobalNetworkByID(ctx, conn, globalNetworkID) if err != nil { - return fmt.Errorf("error reading Network Manager Global Network: %s", err) - } - - // do filtering here - var filteredGlobalNetworks []*networkmanager.GlobalNetwork - if tags, ok := d.GetOk("tags"); ok { - keyValueTags := keyvaluetags.New(tags.(map[string]interface{})).IgnoreAws() - for _, globalNetwork := range output.GlobalNetworks { - tagsMatch := true - if len(keyValueTags) > 0 { - listTags := keyvaluetags.NetworkmanagerKeyValueTags(globalNetwork.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) - tagsMatch = listTags.ContainsAll(keyValueTags) - } - if tagsMatch { - filteredGlobalNetworks = append(filteredGlobalNetworks, globalNetwork) - } - } - } else { - filteredGlobalNetworks = output.GlobalNetworks - } - - if output == nil || len(filteredGlobalNetworks) == 0 { - return errors.New("error reading Network Manager Global Network: no results found") + return diag.Errorf("error reading Network Manager Global Network (%s): %s", globalNetworkID, err) } - if len(filteredGlobalNetworks) > 1 { - return errors.New("error reading Network Manager Global Network: more than one result found. Please try a more specific search criteria.") - } - - globalNetwork := filteredGlobalNetworks[0] - - if globalNetwork == nil { - return errors.New("error reading Network Manager Global Network: empty result") - } - - d.Set("description", globalNetwork.Description) + d.SetId(globalNetworkID) d.Set("arn", globalNetwork.GlobalNetworkArn) + d.Set("description", globalNetwork.Description) + d.Set("global_network_id", globalNetwork.GlobalNetworkId) - if err := d.Set("tags", keyvaluetags.NetworkmanagerKeyValueTags(globalNetwork.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %s", err) + if err := d.Set("tags", KeyValueTags(globalNetwork.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return diag.Errorf("error setting tags: %s", err) } - d.SetId(aws.StringValue(globalNetwork.GlobalNetworkId)) - return nil } diff --git a/website/docs/d/networkmanager_global_network.markdown b/website/docs/d/networkmanager_global_network.markdown index 16abc54870d..bb742693337 100644 --- a/website/docs/d/networkmanager_global_network.markdown +++ b/website/docs/d/networkmanager_global_network.markdown @@ -1,5 +1,5 @@ --- -subcategory: "Transit Gateway Network Manager" +subcategory: "Network Manager" layout: "aws" page_title: "AWS: aws_networkmanager_global_network" description: |- @@ -14,16 +14,13 @@ Retrieve information about a global network. ```hcl data "aws_networkmanager_global_network" "example" { - id = var.global_network_id + global_network_id = var.global_network_id } ``` ## Argument Reference -* `id` - (Optional) The id of the specific global network to retrieve. - -* `tags` - (Optional) A map of tags, each pair of which must exactly match - a pair on the desired global network. +* `global_network_id` - (Required) The id of the specific global network to retrieve. ## Attributes Reference @@ -31,3 +28,4 @@ In addition to all arguments above, the following attributes are exported: * `arn` - The ARN of the global network. * `description` - The description of the global network. +* `tags` - A map of resource tags. \ No newline at end of file From f594f110e6ea6b9926daa7f2c7dc41eb36bb5e37 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 15:46:45 -0500 Subject: [PATCH 051/229] Start work on Global Network data source acceptance tests. --- .../{ignore => }/global_network_data_source_test.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename internal/service/networkmanager/{ignore => }/global_network_data_source_test.go (100%) diff --git a/internal/service/networkmanager/ignore/global_network_data_source_test.go b/internal/service/networkmanager/global_network_data_source_test.go similarity index 100% rename from internal/service/networkmanager/ignore/global_network_data_source_test.go rename to internal/service/networkmanager/global_network_data_source_test.go From f684dea54cb2f1214967bfbc832488e510ad86a1 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 15:53:31 -0500 Subject: [PATCH 052/229] d/aws_networkmanager_global_network: Acceptance tests passing. Acceptance test output: % TF_ACC=1 go test ./internal/service/networkmanager -v -count 1 -parallel 20 -run='TestAccNetworkManagerGlobalNetworkDataSource_' -timeout 180m === RUN TestAccNetworkManagerGlobalNetworkDataSource_basic === PAUSE TestAccNetworkManagerGlobalNetworkDataSource_basic === CONT TestAccNetworkManagerGlobalNetworkDataSource_basic --- PASS: TestAccNetworkManagerGlobalNetworkDataSource_basic (19.11s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 23.849s --- .../global_network_data_source_test.go | 55 ++++++------------- 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/internal/service/networkmanager/global_network_data_source_test.go b/internal/service/networkmanager/global_network_data_source_test.go index b71031f9718..afb786d4e0e 100644 --- a/internal/service/networkmanager/global_network_data_source_test.go +++ b/internal/service/networkmanager/global_network_data_source_test.go @@ -4,68 +4,47 @@ import ( "fmt" "testing" + "github.com/aws/aws-sdk-go/service/networkmanager" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-provider-aws/internal/acctest" ) -func TestAccDataSourceGlobalNetwork_basic(t *testing.T) { - dataSourceByIdName := "data.aws_networkmanager_global_network.test_by_id" - dataSourceByTagsName := "data.aws_networkmanager_global_network.test_by_tags" +func TestAccNetworkManagerGlobalNetworkDataSource_basic(t *testing.T) { + dataSourceName := "data.aws_networkmanager_global_network.test" resourceName := "aws_networkmanager_global_network.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - acctest.PreCheck(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAwsGlobalNetworkDestroy, + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, Steps: []resource.TestStep{ { - Config: testAccDataSourceGlobalNetworkConfig(), + Config: testAccGlobalNetworkDataSourceConfig(rName), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrPair(dataSourceByIdName, "id", resourceName, "id"), - resource.TestCheckResourceAttrPair(dataSourceByIdName, "arn", resourceName, "arn"), - resource.TestCheckResourceAttrPair(dataSourceByIdName, "description", resourceName, "description"), - resource.TestCheckResourceAttrPair(dataSourceByIdName, "tags.Name", resourceName, "tags.Name"), - resource.TestCheckResourceAttrPair(dataSourceByIdName, "tags.OtherTag", resourceName, "tags.OtherTag"), - resource.TestCheckResourceAttrPair(dataSourceByTagsName, "id", resourceName, "id"), - resource.TestCheckResourceAttrPair(dataSourceByTagsName, "arn", resourceName, "arn"), - resource.TestCheckResourceAttrPair(dataSourceByTagsName, "description", resourceName, "description"), - resource.TestCheckResourceAttrPair(dataSourceByTagsName, "tags.Name", resourceName, "tags.Name"), + resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(dataSourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttrPair(dataSourceName, "global_network_id", resourceName, "id"), + resource.TestCheckResourceAttrPair(dataSourceName, "tags.%", resourceName, "tags.%"), ), }, }, }) } -func testAccDataSourceGlobalNetworkConfig() string { +func testAccGlobalNetworkDataSourceConfig(rName string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { description = "test" tags = { - Name = "terraform-testacc-global-network-%d" - OtherTag = "some-value" + Name = %[1]q } } -resource "aws_networkmanager_global_network" "test2" { - description = "test2" - - tags = { - Name = "terraform-testacc-global-network2" - } -} - -data "aws_networkmanager_global_network" "test_by_id" { - id = aws_networkmanager_global_network.test.id -} - -data "aws_networkmanager_global_network" "test_by_tags" { - tags = { - Name = aws_networkmanager_global_network.test.tags["Name"] - } +data "aws_networkmanager_global_network" "test" { + global_network_id = aws_networkmanager_global_network.test.id } -`, sdkacctest.RandInt()) +`, rName) } From 9a2d2fe65574cf5785a6175b24bdc3b0056ee5ff Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 15:58:45 -0500 Subject: [PATCH 053/229] '*.markdown' -> '*.html.markdown'. --- ...anager_device.markdown => networkmanager_device.html.markdown} | 0 ...twork.markdown => networkmanager_global_network.html.markdown} | 0 ...orkmanager_site.markdown => networkmanager_site.html.markdown} | 0 ...anager_device.markdown => networkmanager_device.html.markdown} | 0 ...twork.markdown => networkmanager_global_network.html.markdown} | 0 ...orkmanager_site.markdown => networkmanager_site.html.markdown} | 0 ... => networkmanager_transit_gateway_registration.html.markdown} | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename website/docs/d/{networkmanager_device.markdown => networkmanager_device.html.markdown} (100%) rename website/docs/d/{networkmanager_global_network.markdown => networkmanager_global_network.html.markdown} (100%) rename website/docs/d/{networkmanager_site.markdown => networkmanager_site.html.markdown} (100%) rename website/docs/r/{networkmanager_device.markdown => networkmanager_device.html.markdown} (100%) rename website/docs/r/{networkmanager_global_network.markdown => networkmanager_global_network.html.markdown} (100%) rename website/docs/r/{networkmanager_site.markdown => networkmanager_site.html.markdown} (100%) rename website/docs/r/{networkmanager_transit_gateway_registration.markdown => networkmanager_transit_gateway_registration.html.markdown} (100%) diff --git a/website/docs/d/networkmanager_device.markdown b/website/docs/d/networkmanager_device.html.markdown similarity index 100% rename from website/docs/d/networkmanager_device.markdown rename to website/docs/d/networkmanager_device.html.markdown diff --git a/website/docs/d/networkmanager_global_network.markdown b/website/docs/d/networkmanager_global_network.html.markdown similarity index 100% rename from website/docs/d/networkmanager_global_network.markdown rename to website/docs/d/networkmanager_global_network.html.markdown diff --git a/website/docs/d/networkmanager_site.markdown b/website/docs/d/networkmanager_site.html.markdown similarity index 100% rename from website/docs/d/networkmanager_site.markdown rename to website/docs/d/networkmanager_site.html.markdown diff --git a/website/docs/r/networkmanager_device.markdown b/website/docs/r/networkmanager_device.html.markdown similarity index 100% rename from website/docs/r/networkmanager_device.markdown rename to website/docs/r/networkmanager_device.html.markdown diff --git a/website/docs/r/networkmanager_global_network.markdown b/website/docs/r/networkmanager_global_network.html.markdown similarity index 100% rename from website/docs/r/networkmanager_global_network.markdown rename to website/docs/r/networkmanager_global_network.html.markdown diff --git a/website/docs/r/networkmanager_site.markdown b/website/docs/r/networkmanager_site.html.markdown similarity index 100% rename from website/docs/r/networkmanager_site.markdown rename to website/docs/r/networkmanager_site.html.markdown diff --git a/website/docs/r/networkmanager_transit_gateway_registration.markdown b/website/docs/r/networkmanager_transit_gateway_registration.html.markdown similarity index 100% rename from website/docs/r/networkmanager_transit_gateway_registration.markdown rename to website/docs/r/networkmanager_transit_gateway_registration.html.markdown From ca6bd0fffdd6e89f6018464fcc3db5f3ad9c0db1 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 16:17:42 -0500 Subject: [PATCH 054/229] d/aws_networkmanager_global_networks: New data source. Acceptance test output: % TF_ACC=1 go test ./internal/service/networkmanager -v -count 1 -parallel 20 -run='TestAccNetworkManagerGlobalNetworksDataSource_' -timeout 180m === RUN TestAccNetworkManagerGlobalNetworksDataSource_basic === PAUSE TestAccNetworkManagerGlobalNetworksDataSource_basic === CONT TestAccNetworkManagerGlobalNetworksDataSource_basic --- PASS: TestAccNetworkManagerGlobalNetworksDataSource_basic (20.04s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 23.846s --- internal/provider/provider.go | 3 +- .../global_networks_data_source.go | 56 +++++++++++++++++ .../global_networks_data_source_test.go | 60 +++++++++++++++++++ ...tworkmanager_global_networks.html.markdown | 31 ++++++++++ 4 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 internal/service/networkmanager/global_networks_data_source.go create mode 100644 internal/service/networkmanager/global_networks_data_source_test.go create mode 100644 website/docs/d/networkmanager_global_networks.html.markdown diff --git a/internal/provider/provider.go b/internal/provider/provider.go index b625ecd864c..ce33e52fc86 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -713,7 +713,8 @@ func Provider() *schema.Provider { "aws_neptune_engine_version": neptune.DataSourceEngineVersion(), "aws_neptune_orderable_db_instance": neptune.DataSourceOrderableDBInstance(), - "aws_networkmanager_global_network": networkmanager.DataSourceGlobalNetwork(), + "aws_networkmanager_global_network": networkmanager.DataSourceGlobalNetwork(), + "aws_networkmanager_global_networks": networkmanager.DataSourceGlobalNetworks(), "aws_organizations_delegated_administrators": organizations.DataSourceDelegatedAdministrators(), "aws_organizations_delegated_services": organizations.DataSourceDelegatedServices(), diff --git a/internal/service/networkmanager/global_networks_data_source.go b/internal/service/networkmanager/global_networks_data_source.go new file mode 100644 index 00000000000..21651d3cc04 --- /dev/null +++ b/internal/service/networkmanager/global_networks_data_source.go @@ -0,0 +1,56 @@ +package networkmanager + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" +) + +func DataSourceGlobalNetworks() *schema.Resource { + return &schema.Resource{ + ReadWithoutTimeout: dataSourceGlobalNetworksRead, + + Schema: map[string]*schema.Schema{ + "ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "tags": tftags.TagsSchema(), + }, + } +} + +func dataSourceGlobalNetworksRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig + tagsToMatch := tftags.New(d.Get("tags").(map[string]interface{})).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) + + output, err := FindGlobalNetworks(ctx, conn, &networkmanager.DescribeGlobalNetworksInput{}) + + if err != nil { + return diag.Errorf("error listing Network Manager Global Networks: %s", err) + } + + var globalNetworkIDs []string + + for _, v := range output { + if len(tagsToMatch) > 0 { + if !KeyValueTags(v.Tags).ContainsAll(tagsToMatch) { + continue + } + } + + globalNetworkIDs = append(globalNetworkIDs, aws.StringValue(v.GlobalNetworkId)) + } + + d.SetId(meta.(*conns.AWSClient).Region) + d.Set("ids", globalNetworkIDs) + + return nil +} diff --git a/internal/service/networkmanager/global_networks_data_source_test.go b/internal/service/networkmanager/global_networks_data_source_test.go new file mode 100644 index 00000000000..5fe50b081f8 --- /dev/null +++ b/internal/service/networkmanager/global_networks_data_source_test.go @@ -0,0 +1,60 @@ +package networkmanager_test + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/networkmanager" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" +) + +func TestAccNetworkManagerGlobalNetworksDataSource_basic(t *testing.T) { + dataSourceAllName := "data.aws_networkmanager_global_networks.all" + dataSourceByTagsName := "data.aws_networkmanager_global_networks.by_tags" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccGlobalNetworksDataSourceConfig(rName), + Check: resource.ComposeTestCheckFunc( + acctest.CheckResourceAttrGreaterThanValue(dataSourceAllName, "ids.#", "1"), + resource.TestCheckResourceAttr(dataSourceByTagsName, "ids.#", "1"), + ), + }, + }, + }) +} + +func testAccGlobalNetworksDataSourceConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test1" { + description = "test1" + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_global_network" "test2" { + description = "test2" +} + +data "aws_networkmanager_global_networks" "all" { + depends_on = [aws_networkmanager_global_network.test1, aws_networkmanager_global_network.test2] +} + +data "aws_networkmanager_global_networks" "by_tags" { + tags = { + Name = %[1]q + } + + depends_on = [aws_networkmanager_global_network.test1, aws_networkmanager_global_network.test2] +} +`, rName) +} diff --git a/website/docs/d/networkmanager_global_networks.html.markdown b/website/docs/d/networkmanager_global_networks.html.markdown new file mode 100644 index 00000000000..668487647a8 --- /dev/null +++ b/website/docs/d/networkmanager_global_networks.html.markdown @@ -0,0 +1,31 @@ +--- +subcategory: "Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_global_networks" +description: |- + Retrieve information about global networks. +--- + +# Data Source: aws_networkmanager_global_networks + +Retrieve information about global networks. + +## Example Usage + +```hcl +data "aws_networkmanager_global_networks" "example" { + tags = { + Env = "test" + } +} +``` + +## Argument Reference + +* `tags` - (Optional) Restricts the list to the global networks with these tags. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `ids` - The IDs of the global networks. From add2d8e72ad59200c5c0d754c8e6c17388fb1fdb Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 16:30:33 -0500 Subject: [PATCH 055/229] Start work on Site resource. --- internal/service/networkmanager/{ignore => }/site.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename internal/service/networkmanager/{ignore => }/site.go (100%) diff --git a/internal/service/networkmanager/ignore/site.go b/internal/service/networkmanager/site.go similarity index 100% rename from internal/service/networkmanager/ignore/site.go rename to internal/service/networkmanager/site.go From eec215995771a37dbf95e0dae624b57be483a8d8 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 17:37:34 -0500 Subject: [PATCH 056/229] r/aws_networkmanager_site: Modernize resource. --- internal/provider/provider.go | 1 + .../service/networkmanager/global_network.go | 6 +- internal/service/networkmanager/site.go | 410 +++++++++++------- .../docs/r/networkmanager_site.html.markdown | 5 +- 4 files changed, 267 insertions(+), 155 deletions(-) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index ce33e52fc86..9e8d71acb8c 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1581,6 +1581,7 @@ func Provider() *schema.Provider { "aws_networkfirewall_rule_group": networkfirewall.ResourceRuleGroup(), "aws_networkmanager_global_network": networkmanager.ResourceGlobalNetwork(), + "aws_networkmanager_site": networkmanager.ResourceSite(), "aws_opsworks_application": opsworks.ResourceApplication(), "aws_opsworks_custom_layer": opsworks.ResourceCustomLayer(), diff --git a/internal/service/networkmanager/global_network.go b/internal/service/networkmanager/global_network.go index 04c883379d4..7a20e4576f8 100644 --- a/internal/service/networkmanager/global_network.go +++ b/internal/service/networkmanager/global_network.go @@ -154,7 +154,7 @@ func resourceGlobalNetworkDelete(ctx context.Context, d *schema.ResourceData, me conn := meta.(*conns.AWSClient).NetworkManagerConn log.Printf("[DEBUG] Deleting Network Manager Global Network: %s", d.Id()) - _, err := tfresource.RetryWhenAWSErrCodeEqualsContext(ctx, globalNetworkValidationException, func() (interface{}, error) { + _, err := tfresource.RetryWhenAWSErrCodeEqualsContext(ctx, globalNetworkValidationExceptionTimeout, func() (interface{}, error) { return conn.DeleteGlobalNetworkWithContext(ctx, &networkmanager.DeleteGlobalNetworkInput{ GlobalNetworkId: aws.String(d.Id()), }) @@ -252,7 +252,7 @@ func statusGlobalNetworkState(ctx context.Context, conn *networkmanager.NetworkM return nil, "", err } - return output, string(*output.State), nil + return output, aws.StringValue(output.State), nil } } @@ -309,5 +309,5 @@ func waitGlobalNetworkUpdated(ctx context.Context, conn *networkmanager.NetworkM } const ( - globalNetworkValidationException = 2 * time.Minute + globalNetworkValidationExceptionTimeout = 2 * time.Minute ) diff --git a/internal/service/networkmanager/site.go b/internal/service/networkmanager/site.go index 2188568d89a..eff1e10abdf 100644 --- a/internal/service/networkmanager/site.go +++ b/internal/service/networkmanager/site.go @@ -1,6 +1,7 @@ package networkmanager import ( + "context" "fmt" "log" "strings" @@ -9,50 +10,62 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" - "github.com/terraform-providers/terraform-provider-aws/internal/keyvaluetags" + "github.com/hashicorp/terraform-provider-aws/internal/verify" ) func ResourceSite() *schema.Resource { return &schema.Resource{ - Create: ResourceSiteCreate, - Read: ResourceSiteRead, - Update: ResourceSiteUpdate, - Delete: ResourceSiteDelete, - Importer: &schema.ResourceImporter{ - State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - d.Set("arn", d.Id()) + CreateWithoutTimeout: resourceSiteCreate, + ReadWithoutTimeout: resourceSiteRead, + UpdateWithoutTimeout: resourceSiteUpdate, + DeleteWithoutTimeout: resourceSiteDelete, - idErr := fmt.Errorf("Expected ID in format of arn:aws:networkmanager::ACCOUNTID:site/GLOBALNETWORKID/SITEID and provided: %s", d.Id()) + Importer: &schema.ResourceImporter{ + StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + parsedARN, err := arn.Parse(d.Id()) - resARN, err := arn.Parse(d.Id()) if err != nil { - return nil, idErr + return nil, fmt.Errorf("error parsing ARN (%s): %w", d.Id(), err) } - identifiers := strings.TrimPrefix(resARN.Resource, "site/") - identifierParts := strings.Split(identifiers, "/") - if len(identifierParts) != 2 { - return nil, idErr + // See https://docs.aws.amazon.com/service-authorization/latest/reference/list_networkmanager.html#networkmanager-resources-for-iam-policies. + resourceParts := strings.Split(parsedARN.Resource, "/") + + if actual, expected := len(resourceParts), 3; actual < expected { + return nil, fmt.Errorf("expected at least %d resource parts in ARN (%s), got: %d", expected, d.Id(), actual) } - d.SetId(identifierParts[1]) - d.Set("global_network_id", identifierParts[0]) + + d.SetId(resourceParts[2]) + d.Set("global_network_id", resourceParts[1]) return []*schema.ResourceData{d}, nil }, }, + CustomizeDiff: verify.SetTagsDiff, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Update: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + Schema: map[string]*schema.Schema{ "arn": { Type: schema.TypeString, Computed: true, }, "description": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 256), }, "global_network_id": { Type: schema.TypeString, @@ -80,237 +93,334 @@ func ResourceSite() *schema.Resource { }, }, }, - "tags": tagsSchema(), + "tags": tftags.TagsSchema(), + "tags_all": tftags.TagsSchemaComputed(), }, } } -func ResourceSiteCreate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn +func resourceSiteCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{}))) + globalNetworkID := d.Get("global_network_id").(string) input := &networkmanager.CreateSiteInput{ - Description: aws.String(d.Get("description").(string)), - GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), - Location: expandLocation(d.Get("location").([]interface{})), - Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().NetworkmanagerTags(), + GlobalNetworkId: aws.String(globalNetworkID), } - log.Printf("[DEBUG] Creating Network Manager Site: %s", input) - output, err := conn.CreateSite(input) - if err != nil { - return fmt.Errorf("error creating Network Manager Site: %s", err) + if v, ok := d.GetOk("description"); ok { + input.Description = aws.String(v.(string)) } - d.SetId(aws.StringValue(output.Site.SiteId)) - d.Set("global_network_id", aws.StringValue(output.Site.GlobalNetworkId)) + if v, ok := d.GetOk("location"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.Location = expandLocation(v.([]interface{})[0].(map[string]interface{})) + } - stateConf := &resource.StateChangeConf{ - Pending: []string{networkmanager.SiteStatePending}, - Target: []string{networkmanager.SiteStateAvailable}, - Refresh: networkmanagerSiteRefreshFunc(conn, aws.StringValue(output.Site.GlobalNetworkId), aws.StringValue(output.Site.SiteId)), - Timeout: 10 * time.Minute, + if len(tags) > 0 { + input.Tags = Tags(tags.IgnoreAWS()) } - _, err = stateConf.WaitForState() + log.Printf("[DEBUG] Creating Network Manager Site: %s", input) + output, err := conn.CreateSiteWithContext(ctx, input) + if err != nil { - return fmt.Errorf("error waiting for Network Manager Site (%s) availability: %s", d.Id(), err) + return diag.Errorf("error creating Network Manager Site: %s", err) } - return ResourceSiteRead(d, meta) -} + d.SetId(aws.StringValue(output.Site.SiteId)) -func ResourceSiteRead(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn - ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + if _, err := waitSiteCreated(ctx, conn, globalNetworkID, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { + return diag.Errorf("error waiting for Network Manager Site (%s) create: %s", d.Id(), err) + } - site, err := networkmanagerDescribeSite(conn, d.Get("global_network_id").(string), d.Id()) + return resourceSiteRead(ctx, d, meta) +} - if tfawserr.ErrCodeEquals(err, "InvalidSiteID.NotFound", "") { - log.Printf("[WARN] Network Manager Site (%s) not found, removing from state", d.Id()) - d.SetId("") - return nil - } +func resourceSiteRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig - if err != nil { - return fmt.Errorf("error reading Network Manager Site: %s", err) - } + globalNetworkID := d.Get("global_network_id").(string) + site, err := FindSiteByTwoPartKey(ctx, conn, globalNetworkID, d.Id()) - if site == nil { - log.Printf("[WARN] Network Manager Site (%s) not found, removing from state", d.Id()) + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Network Manager Site %s not found, removing from state", d.Id()) d.SetId("") return nil } - if aws.StringValue(site.State) == networkmanager.SiteStateDeleting { - log.Printf("[WARN] Network Manager Site (%s) in deleted state (%s), removing from state", d.Id(), aws.StringValue(site.State)) - d.SetId("") - return nil + if err != nil { + return diag.Errorf("error reading Network Manager Site (%s): %s", d.Id(), err) } d.Set("arn", site.SiteArn) d.Set("description", site.Description) + if site.Location != nil { + if err := d.Set("location", []interface{}{flattenLocation(site.Location)}); err != nil { + return diag.Errorf("error setting location: %s", err) + } + } else { + d.Set("location", nil) + } + + tags := KeyValueTags(site.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) - if err := d.Set("location", flattenLocation(site.Location)); err != nil { - return fmt.Errorf("error setting location: %s", err) + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return diag.Errorf("error setting tags: %s", err) } - if err := d.Set("tags", keyvaluetags.NetworkmanagerKeyValueTags(site.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %s", err) + if err := d.Set("tags_all", tags.Map()); err != nil { + return diag.Errorf("error setting tags_all: %s", err) } return nil } -func ResourceSiteUpdate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn +func resourceSiteUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn if d.HasChanges("description", "location") { - request := &networkmanager.UpdateSiteInput{ - Description: aws.String(d.Get("description").(string)), - GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), - Location: expandLocation(d.Get("location").([]interface{})), + globalNetworkID := d.Get("global_network_id").(string) + input := &networkmanager.UpdateSiteInput{ + GlobalNetworkId: aws.String(globalNetworkID), SiteId: aws.String(d.Id()), } - _, err := conn.UpdateSite(request) + if v, ok := d.GetOk("description"); ok { + input.Description = aws.String(v.(string)) + } + + if v, ok := d.GetOk("location"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.Location = expandLocation(v.([]interface{})[0].(map[string]interface{})) + } + + log.Printf("[DEBUG] Updating Network Manager Site: %s", input) + _, err := conn.UpdateSiteWithContext(ctx, input) + if err != nil { - return fmt.Errorf("Failure updating Network Manager Site (%s): %s", d.Id(), err) + return diag.Errorf("error updating Network Manager Site (%s): %s", d.Id(), err) + } + + if _, err := waitSiteUpdated(ctx, conn, globalNetworkID, d.Id(), d.Timeout(schema.TimeoutUpdate)); err != nil { + return diag.Errorf("error waiting for Network Manager Site (%s) update: %s", d.Id(), err) } } - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") - if err := keyvaluetags.NetworkmanagerUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { - return fmt.Errorf("error updating Network Manager Site (%s) tags: %s", d.Id(), err) + if err := UpdateTags(conn, d.Get("arn").(string), o, n); err != nil { + return diag.Errorf("error updating Network Manager Site (%s) tags: %s", d.Id(), err) } } + return resourceSiteRead(ctx, d, meta) +} + +func resourceSiteDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + globalNetworkID := d.Get("global_network_id").(string) + + log.Printf("[DEBUG] Deleting Network Manager Site: %s", d.Id()) + _, err := tfresource.RetryWhenAWSErrCodeEqualsContext(ctx, siteValidationExceptionTimeout, func() (interface{}, error) { + return conn.DeleteSiteWithContext(ctx, &networkmanager.DeleteSiteInput{ + GlobalNetworkId: aws.String(globalNetworkID), + SiteId: aws.String(d.Id()), + }) + }, networkmanager.ErrCodeValidationException) + + if err != nil { + return diag.Errorf("error deleting Network Manager Site (%s): %s", d.Id(), err) + } + + if _, err := waitSiteDeleted(ctx, conn, globalNetworkID, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil { + return diag.Errorf("error waiting for Network Manager Site (%s) delete: %s", d.Id(), err) + } + return nil } -func ResourceSiteDelete(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn +func FindSite(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.GetSitesInput) (*networkmanager.Site, error) { + output, err := FindSites(ctx, conn, input) - input := &networkmanager.DeleteSiteInput{ - GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), - SiteId: aws.String(d.Id()), + if err != nil { + return nil, err } - log.Printf("[DEBUG] Deleting Network Manager Site (%s): %s", d.Id(), input) - err := resource.Retry(2*time.Minute, func() *resource.RetryError { - _, err := conn.DeleteSite(input) + if len(output) == 0 || output[0] == nil { + return nil, tfresource.NewEmptyResultError(input) + } - if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Link Associations") { - return resource.RetryableError(err) - } + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } - if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Device") { - return resource.RetryableError(err) + return output[0], nil +} + +func FindSites(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.GetSitesInput) ([]*networkmanager.Site, error) { + var output []*networkmanager.Site + + err := conn.GetSitesPagesWithContext(ctx, input, func(page *networkmanager.GetSitesOutput, lastPage bool) bool { + if page == nil { + return !lastPage } - if err != nil { - return resource.NonRetryableError(err) + for _, v := range page.Sites { + if v == nil { + continue + } + + output = append(output, v) } - return nil + return !lastPage }) - if tfresource.TimedOut(err) { - _, err = conn.DeleteSite(input) + if err != nil { + return nil, err } - if tfawserr.ErrCodeEquals(err, "InvalidSiteID.NotFound", "") { - return nil + return output, nil +} + +func FindSiteByTwoPartKey(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, siteID string) (*networkmanager.Site, error) { + input := &networkmanager.GetSitesInput{ + GlobalNetworkId: aws.String(globalNetworkID), + SiteIds: aws.StringSlice([]string{siteID}), } + output, err := FindSite(ctx, conn, input) + if err != nil { - return fmt.Errorf("error deleting Network Manager Site: %s", err) + return nil, err } - if err := waitForSiteDeletion(conn, d.Get("global_network_id").(string), d.Id()); err != nil { - return fmt.Errorf("error waiting for Network Manager Site (%s) deletion: %s", d.Id(), err) + // Eventual consistency check. + if aws.StringValue(output.GlobalNetworkId) != globalNetworkID || aws.StringValue(output.SiteId) != siteID { + return nil, &resource.NotFoundError{ + LastRequest: input, + } } - return nil + return output, nil } -func networkmanagerSiteRefreshFunc(conn *networkmanager.NetworkManager, globalNetworkID, siteID string) resource.StateRefreshFunc { +func statusSiteState(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, siteID string) resource.StateRefreshFunc { return func() (interface{}, string, error) { - site, err := networkmanagerDescribeSite(conn, globalNetworkID, siteID) + output, err := FindSiteByTwoPartKey(ctx, conn, globalNetworkID, siteID) - if tfawserr.ErrCodeEquals(err, "InvalidSiteID.NotFound", "") { - return nil, "DELETED", nil + if tfresource.NotFound(err) { + return nil, "", nil } if err != nil { - return nil, "", fmt.Errorf("error reading Network Manager Site (%s): %s", siteID, err) - } - - if site == nil { - return nil, "DELETED", nil + return nil, "", err } - return site, aws.StringValue(site.State), nil + return output, aws.StringValue(output.State), nil } } -func networkmanagerDescribeSite(conn *networkmanager.NetworkManager, globalNetworkID, siteID string) (*networkmanager.Site, error) { - input := &networkmanager.GetSitesInput{ - GlobalNetworkId: aws.String(globalNetworkID), - SiteIds: []*string{aws.String(siteID)}, +func waitSiteCreated(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, siteID string, timeout time.Duration) (*networkmanager.Site, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.SiteStatePending}, + Target: []string{networkmanager.SiteStateAvailable}, + Timeout: timeout, + Refresh: statusSiteState(ctx, conn, globalNetworkID, siteID), } - log.Printf("[DEBUG] Reading Network Manager Site (%s): %s", siteID, input) - for { - output, err := conn.GetSites(input) - - if err != nil { - return nil, err - } + outputRaw, err := stateConf.WaitForStateContext(ctx) - if output == nil || len(output.Sites) == 0 { - return nil, nil - } + if output, ok := outputRaw.(*networkmanager.Site); ok { + return output, err + } - for _, site := range output.Sites { - if site == nil { - continue - } + return nil, err +} - if aws.StringValue(site.SiteId) == siteID { - return site, nil - } - } +func waitSiteDeleted(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, siteID string, timeout time.Duration) (*networkmanager.Site, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.SiteStateDeleting}, + Target: []string{}, + Timeout: timeout, + Refresh: statusSiteState(ctx, conn, globalNetworkID, siteID), + } - if aws.StringValue(output.NextToken) == "" { - break - } + outputRaw, err := stateConf.WaitForStateContext(ctx) - input.NextToken = output.NextToken + if output, ok := outputRaw.(*networkmanager.Site); ok { + return output, err } - return nil, nil + return nil, err } -func waitForSiteDeletion(conn *networkmanager.NetworkManager, globalNetworkID, siteID string) error { +func waitSiteUpdated(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, siteID string, timeout time.Duration) (*networkmanager.Site, error) { stateConf := &resource.StateChangeConf{ - Pending: []string{ - networkmanager.SiteStateAvailable, - networkmanager.SiteStateDeleting, - }, - Target: []string{""}, - Refresh: networkmanagerSiteRefreshFunc(conn, globalNetworkID, siteID), - Timeout: 10 * time.Minute, - NotFoundChecks: 1, + Pending: []string{networkmanager.SiteStateUpdating}, + Target: []string{networkmanager.SiteStateAvailable}, + Timeout: timeout, + Refresh: statusSiteState(ctx, conn, globalNetworkID, siteID), + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*networkmanager.Site); ok { + return output, err + } + + return nil, err +} + +const ( + siteValidationExceptionTimeout = 2 * time.Minute +) + +func expandLocation(tfMap map[string]interface{}) *networkmanager.Location { + if tfMap == nil { + return nil } - log.Printf("[DEBUG] Waiting for Network Manager Site (%s) deletion", siteID) - _, err := stateConf.WaitForState() + apiObject := &networkmanager.Location{} - if tfresource.NotFound(err) { + if v, ok := tfMap["address"].(string); ok && v != "" { + apiObject.Address = aws.String(v) + } + + if v, ok := tfMap["latitude"].(string); ok && v != "" { + apiObject.Latitude = aws.String(v) + } + + if v, ok := tfMap["longitude"].(string); ok && v != "" { + apiObject.Longitude = aws.String(v) + } + + return apiObject +} + +func flattenLocation(apiObject *networkmanager.Location) map[string]interface{} { + if apiObject == nil { return nil } - return err + tfMap := map[string]interface{}{} + + if v := apiObject.Address; v != nil { + tfMap["address"] = aws.StringValue(v) + } + + if v := apiObject.Latitude; v != nil { + tfMap["latitude"] = aws.StringValue(v) + } + + if v := apiObject.Longitude; v != nil { + tfMap["longitude"] = aws.StringValue(v) + } + + return tfMap } diff --git a/website/docs/r/networkmanager_site.html.markdown b/website/docs/r/networkmanager_site.html.markdown index b719836735e..b686e2f3911 100644 --- a/website/docs/r/networkmanager_site.html.markdown +++ b/website/docs/r/networkmanager_site.html.markdown @@ -1,5 +1,5 @@ --- -subcategory: "Transit Gateway Network Manager" +subcategory: "Network Manager" layout: "aws" page_title: "AWS: aws_networkmanager_site" description: |- @@ -28,7 +28,7 @@ The following arguments are supported: * `global_network_id` - (Required) The ID of the Global Network to create the site in. * `description` - (Optional) Description of the Site. * `location` - (Optional) The site location as documented below. -* `tags` - (Optional) Key-value tags for the Site. +* `tags` - (Optional) Key-value tags for the Site. If configured with a provider [`default_tags` configuration block](https://www.terraform.io/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. The `location` object supports the following: @@ -41,6 +41,7 @@ The `location` object supports the following: In addition to all arguments above, the following attributes are exported: * `arn` - Site Amazon Resource Name (ARN) +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](https://www.terraform.io/docs/providers/aws/index.html#default_tags-configuration-block). ## Import From 45c8ccdfc46cc57cedbcc0be6c44e883bc880b9f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 17:49:00 -0500 Subject: [PATCH 057/229] Start work on Site acceptance tests. --- internal/service/networkmanager/{ignore => }/site_test.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename internal/service/networkmanager/{ignore => }/site_test.go (100%) diff --git a/internal/service/networkmanager/ignore/site_test.go b/internal/service/networkmanager/site_test.go similarity index 100% rename from internal/service/networkmanager/ignore/site_test.go rename to internal/service/networkmanager/site_test.go From c61ca0da27369fcff9f5d783ca5249b1058a3eb3 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 2 Mar 2022 18:20:04 -0500 Subject: [PATCH 058/229] r/aws_networkmanager_site: Basic acceptance test passing. Acceptance test output: % TF_ACC=1 go test ./internal/service/networkmanager -v -count 1 -parallel 20 -run='TestAccNetworkManagerSite_' -timeout 180m === RUN TestAccNetworkManagerSite_basic === PAUSE TestAccNetworkManagerSite_basic === CONT TestAccNetworkManagerSite_basic --- PASS: TestAccNetworkManagerSite_basic (34.51s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 38.979s --- internal/service/networkmanager/errors.go | 27 +++ internal/service/networkmanager/site.go | 7 + internal/service/networkmanager/site_test.go | 205 ++++--------------- 3 files changed, 73 insertions(+), 166 deletions(-) create mode 100644 internal/service/networkmanager/errors.go diff --git a/internal/service/networkmanager/errors.go b/internal/service/networkmanager/errors.go new file mode 100644 index 00000000000..19bfd542f89 --- /dev/null +++ b/internal/service/networkmanager/errors.go @@ -0,0 +1,27 @@ +package networkmanager + +import ( + "errors" + "strings" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" +) + +// validationExceptionMessageContains returns true if the error matches all these conditions: +// * err is of type networkmanager.ValidationException +// * ValidationException.Reason equals reason +// * ValidationException.Fields.Message contains message +func validationExceptionMessageContains(err error, reason string, message string) bool { + var validationException *networkmanager.ValidationException + + if errors.As(err, &validationException) && aws.StringValue(validationException.Reason) == reason { + for _, v := range validationException.Fields { + if strings.Contains(aws.StringValue(v.Message), message) { + return true + } + } + } + + return false +} diff --git a/internal/service/networkmanager/site.go b/internal/service/networkmanager/site.go index eff1e10abdf..c5836083a74 100644 --- a/internal/service/networkmanager/site.go +++ b/internal/service/networkmanager/site.go @@ -281,6 +281,13 @@ func FindSites(ctx context.Context, conn *networkmanager.NetworkManager, input * return !lastPage }) + if validationExceptionMessageContains(err, networkmanager.ValidationExceptionReasonFieldValidationFailed, "Global network not found") { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + if err != nil { return nil, err } diff --git a/internal/service/networkmanager/site_test.go b/internal/service/networkmanager/site_test.go index 44e94c5c8dd..b32bef0238c 100644 --- a/internal/service/networkmanager/site_test.go +++ b/internal/service/networkmanager/site_test.go @@ -1,96 +1,38 @@ -package networkmanager +package networkmanager_test import ( + "context" "fmt" - "log" "testing" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" - "github.com/hashicorp/go-multierror" + 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" "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tfnetworkmanager "github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -func init() { - resource.AddTestSweepers("aws_networkmanager_site", &resource.Sweeper{ - Name: "aws_networkmanager_site", - F: testSweepSite, - }) -} - -func testSweepSite(region string) error { - client, err := sharedClientForRegion(region) - if err != nil { - return fmt.Errorf("error getting client: %s", err) - } - conn := client.(*AWSClient).networkmanagerconn - var sweeperErrs *multierror.Error - - err = conn.GetSitesPages(&networkmanager.GetSitesInput{}, - func(page *networkmanager.GetSitesOutput, lastPage bool) bool { - for _, site := range page.Sites { - input := &networkmanager.DeleteSiteInput{ - GlobalNetworkId: site.GlobalNetworkId, - SiteId: site.SiteId, - } - id := aws.StringValue(site.SiteId) - globalNetworkID := aws.StringValue(site.GlobalNetworkId) - - log.Printf("[INFO] Deleting Network Manager Site: %s", id) - _, err := conn.DeleteSite(input) - - if tfawserr.ErrCodeEquals(err, "InvalidSiteID.NotFound", "") { - continue - } - - if err != nil { - sweeperErr := fmt.Errorf("failed to delete Network Manager Site %s: %s", id, err) - log.Printf("[ERROR] %s", sweeperErr) - sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) - continue - } - - if err := waitForSiteDeletion(conn, globalNetworkID, id); err != nil { - sweeperErr := fmt.Errorf("error waiting for Network Manager Site (%s) deletion: %s", id, err) - log.Printf("[ERROR] %s", sweeperErr) - sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) - continue - } - } - return !lastPage - }) - if testSweepSkipSweepError(err) { - log.Printf("[WARN] Skipping Network Manager Site sweep for %s: %s", region, err) - return nil - } - - if err != nil { - return fmt.Errorf("Error retrieving Network Manager Sites: %s", err) - } - - return sweeperErrs.ErrorOrNil() -} - -func TestAccSite_basic(t *testing.T) { +func TestAccNetworkManagerSite_basic(t *testing.T) { resourceName := "aws_networkmanager_site.test" - gloablNetworkResourceName := "aws_networkmanager_global_network.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAwsSiteDestroy, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckSiteDestroy, Steps: []resource.TestStep{ { - Config: testAccSiteConfig("test"), + Config: testAccSiteConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsSiteExists(resourceName), + testAccCheckSiteExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "arn"), - resource.TestCheckResourceAttr(resourceName, "description", "test"), - resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetworkResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "description", ""), resource.TestCheckResourceAttr(resourceName, "location.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, { @@ -99,23 +41,11 @@ func TestAccSite_basic(t *testing.T) { ImportStateIdFunc: testAccSiteImportStateIdFunc(resourceName), ImportStateVerify: true, }, - { - Config: testAccSiteConfig_Update("test updated", "18.0029784", "-76.7897987"), - Check: resource.ComposeTestCheckFunc( - testAccCheckAwsSiteExists(resourceName), - resource.TestCheckResourceAttrSet(resourceName, "arn"), - resource.TestCheckResourceAttr(resourceName, "description", "test updated"), - resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetworkResourceName, "id"), - resource.TestCheckResourceAttr(resourceName, "location.#", "1"), - resource.TestCheckResourceAttr(resourceName, "location.0.address", ""), - resource.TestCheckResourceAttr(resourceName, "location.0.latitude", "18.0029784"), - resource.TestCheckResourceAttr(resourceName, "location.0.longitude", "-76.7897987"), - ), - }, }, }) } +/* func TestAccSite_tags(t *testing.T) { resourceName := "aws_networkmanager_site.test" description := "test" @@ -162,124 +92,67 @@ func TestAccSite_tags(t *testing.T) { }, }) } +*/ -func testAccCheckAwsSiteDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn +func testAccCheckSiteDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_networkmanager_site" { continue } - site, err := networkmanagerDescribeSite(conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) - if err != nil { - if tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeValidationException, "") { - return nil - } - return err - } + _, err := tfnetworkmanager.FindSiteByTwoPartKey(context.TODO(), conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) - if site == nil { + if tfresource.NotFound(err) { continue } - return fmt.Errorf("Expected Site to be destroyed, %s found", rs.Primary.ID) + if err != nil { + return err + } + + return fmt.Errorf("Network Manager Site %s still exists", rs.Primary.ID) } return nil } -func testAccCheckAwsSiteExists(name string) resource.TestCheckFunc { +func testAccCheckSiteExists(n string) resource.TestCheckFunc { return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[name] + rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not found: %s", name) + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No Network Manager Site ID is set") } - conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn - site, err := networkmanagerDescribeSite(conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) + _, err := tfnetworkmanager.FindSiteByTwoPartKey(context.TODO(), conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) if err != nil { return err } - if site == nil { - return fmt.Errorf("Network Manager Site not found") - } - - if aws.StringValue(site.State) != networkmanager.SiteStateAvailable && aws.StringValue(site.State) != networkmanager.SiteStatePending { - return fmt.Errorf("Network Manager Site (%s) exists in (%s) state", rs.Primary.ID, aws.StringValue(site.State)) - } - - return err + return nil } } -func testAccSiteConfig(description string) string { - return fmt.Sprintf(` -resource "aws_networkmanager_global_network" "test" { - description = "test" -} - -resource "aws_networkmanager_site" "test" { - description = %q - global_network_id = aws_networkmanager_global_network.test.id -} -`, description) -} - -func testAccSiteConfigTags1(description, tagKey1, tagValue1 string) string { - return fmt.Sprintf(` -resource "aws_networkmanager_global_network" "test" { - description = "test" -} - -resource "aws_networkmanager_site" "test" { - description = %q - global_network_id = aws_networkmanager_global_network.test.id - - tags = { - %q = %q - } -} -`, description, tagKey1, tagValue1) -} - -func testAccSiteConfigTags2(description, tagKey1, tagValue1, tagKey2, tagValue2 string) string { +func testAccSiteConfig(rName string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { - description = "test" -} - -resource "aws_networkmanager_site" "test" { - description = %q - global_network_id = aws_networkmanager_global_network.test.id - tags = { - %q = %q - %q = %q + Name = %[1]q } } -`, description, tagKey1, tagValue1, tagKey2, tagValue2) -} - -func testAccSiteConfig_Update(description, latitude, longitude string) string { - return fmt.Sprintf(` -resource "aws_networkmanager_global_network" "test" { - description = "test" -} resource "aws_networkmanager_site" "test" { - description = %q global_network_id = aws_networkmanager_global_network.test.id - - location { - latitude = %q - longitude = %q - } } -`, description, latitude, longitude) +`, rName) } func testAccSiteImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { From 4a21bdb32c94fbcf395218895fb1a5bec02a951e Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 11:44:46 -0500 Subject: [PATCH 059/229] r/aws_networkmanager_site: All acceptance tests passing. Acceptance test output: % TF_ACC=1 go test ./internal/service/networkmanager -v -count 1 -parallel 20 -run='TestAccNetworkManagerSite_' -timeout 180m === RUN TestAccNetworkManagerSite_basic === PAUSE TestAccNetworkManagerSite_basic === RUN TestAccNetworkManagerSite_disappears === PAUSE TestAccNetworkManagerSite_disappears === RUN TestAccNetworkManagerSite_tags === PAUSE TestAccNetworkManagerSite_tags === RUN TestAccNetworkManagerSite_description === PAUSE TestAccNetworkManagerSite_description === RUN TestAccNetworkManagerSite_location === PAUSE TestAccNetworkManagerSite_location === CONT TestAccNetworkManagerSite_basic === CONT TestAccNetworkManagerSite_description === CONT TestAccNetworkManagerSite_disappears === CONT TestAccNetworkManagerSite_tags === CONT TestAccNetworkManagerSite_location --- PASS: TestAccNetworkManagerSite_disappears (23.95s) --- PASS: TestAccNetworkManagerSite_basic (27.89s) --- PASS: TestAccNetworkManagerSite_location (43.13s) --- PASS: TestAccNetworkManagerSite_description (43.36s) --- PASS: TestAccNetworkManagerSite_tags (56.64s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 60.295s --- internal/service/networkmanager/site.go | 10 +- internal/service/networkmanager/site_test.go | 228 +++++++++++++++++-- 2 files changed, 216 insertions(+), 22 deletions(-) diff --git a/internal/service/networkmanager/site.go b/internal/service/networkmanager/site.go index c5836083a74..32bc1cc7a64 100644 --- a/internal/service/networkmanager/site.go +++ b/internal/service/networkmanager/site.go @@ -226,12 +226,10 @@ func resourceSiteDelete(ctx context.Context, d *schema.ResourceData, meta interf globalNetworkID := d.Get("global_network_id").(string) log.Printf("[DEBUG] Deleting Network Manager Site: %s", d.Id()) - _, err := tfresource.RetryWhenAWSErrCodeEqualsContext(ctx, siteValidationExceptionTimeout, func() (interface{}, error) { - return conn.DeleteSiteWithContext(ctx, &networkmanager.DeleteSiteInput{ - GlobalNetworkId: aws.String(globalNetworkID), - SiteId: aws.String(d.Id()), - }) - }, networkmanager.ErrCodeValidationException) + _, err := conn.DeleteSiteWithContext(ctx, &networkmanager.DeleteSiteInput{ + GlobalNetworkId: aws.String(globalNetworkID), + SiteId: aws.String(d.Id()), + }) if err != nil { return diag.Errorf("error deleting Network Manager Site (%s): %s", d.Id(), err) diff --git a/internal/service/networkmanager/site_test.go b/internal/service/networkmanager/site_test.go index b32bef0238c..6ebb0989f4c 100644 --- a/internal/service/networkmanager/site_test.go +++ b/internal/service/networkmanager/site_test.go @@ -45,21 +45,42 @@ func TestAccNetworkManagerSite_basic(t *testing.T) { }) } -/* -func TestAccSite_tags(t *testing.T) { +func TestAccNetworkManagerSite_disappears(t *testing.T) { resourceName := "aws_networkmanager_site.test" - description := "test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAwsSiteDestroy, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckSiteDestroy, Steps: []resource.TestStep{ { - Config: testAccSiteConfigTags1(description, "key1", "value1"), + Config: testAccSiteConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsSiteExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "description", "test"), + testAccCheckSiteExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfnetworkmanager.ResourceSite(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccNetworkManagerSite_tags(t *testing.T) { + resourceName := "aws_networkmanager_site.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckSiteDestroy, + Steps: []resource.TestStep{ + { + Config: testAccSiteConfigTags1(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckSiteExists(resourceName), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), ), @@ -71,20 +92,18 @@ func TestAccSite_tags(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccSiteConfigTags2(description, "key1", "value1updated", "key2", "value2"), + Config: testAccSiteConfigTags2(rName, "key1", "value1updated", "key2", "value2"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsSiteExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "description", "test"), + testAccCheckSiteExists(resourceName), resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), ), }, { - Config: testAccSiteConfigTags1(description, "key2", "value2"), + Config: testAccSiteConfigTags1(rName, "key2", "value2"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsSiteExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "description", "test"), + testAccCheckSiteExists(resourceName), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), ), @@ -92,7 +111,80 @@ func TestAccSite_tags(t *testing.T) { }, }) } -*/ + +func TestAccNetworkManagerSite_description(t *testing.T) { + resourceName := "aws_networkmanager_site.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckSiteDestroy, + Steps: []resource.TestStep{ + { + Config: testAccSiteDescriptionConfig(rName, "description1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckSiteExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "description1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccSiteImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, + { + Config: testAccSiteDescriptionConfig(rName, "description2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckSiteExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "description2"), + ), + }, + }, + }) +} + +func TestAccNetworkManagerSite_location(t *testing.T) { + resourceName := "aws_networkmanager_site.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckSiteDestroy, + Steps: []resource.TestStep{ + { + Config: testAccSiteLocationConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckSiteExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "location.#", "1"), + resource.TestCheckResourceAttr(resourceName, "location.0.address", "Stuart, FL"), + resource.TestCheckResourceAttr(resourceName, "location.0.latitude", "27.198"), + resource.TestCheckResourceAttr(resourceName, "location.0.longitude", "-80.253"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccSiteImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, + { + Config: testAccSiteLocationUpdatedConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckSiteExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "location.#", "1"), + resource.TestCheckResourceAttr(resourceName, "location.0.address", "Brisbane, QLD"), + resource.TestCheckResourceAttr(resourceName, "location.0.latitude", "-27.470"), + resource.TestCheckResourceAttr(resourceName, "location.0.longitude", "153.026"), + ), + }, + }, + }) +} func testAccCheckSiteDestroy(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn @@ -150,7 +242,111 @@ resource "aws_networkmanager_global_network" "test" { } resource "aws_networkmanager_site" "test" { - global_network_id = aws_networkmanager_global_network.test.id + global_network_id = aws_networkmanager_global_network.test.id +} +`, rName) +} + +func testAccSiteConfigTags1(rName, tagKey1, tagValue1 string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + %[2]q = %[3]q + } +} +`, rName, tagKey1, tagValue1) +} + +func testAccSiteConfigTags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + %[2]q = %[3]q + %[4]q = %[5]q + } +} +`, rName, tagKey1, tagValue1, tagKey2, tagValue2) +} + +func testAccSiteDescriptionConfig(rName, description string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + description = %[2]q + + tags = { + Name = %[1]q + } +} +`, rName, description) +} + +func testAccSiteLocationConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + location { + address = "Stuart, FL" + latitude = "27.198" + longitude = "-80.253" + } + + tags = { + Name = %[1]q + } +} +`, rName) +} + +func testAccSiteLocationUpdatedConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + location { + address = "Brisbane, QLD" + latitude = "-27.470" + longitude = "153.026" + } + + tags = { + Name = %[1]q + } } `, rName) } From c57cf8b2cff45f34cf99d08923d5df7108b7ac3b Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 12:42:22 -0500 Subject: [PATCH 060/229] Add CHANGELOG entries. --- .changelog/13251.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .changelog/13251.txt diff --git a/.changelog/13251.txt b/.changelog/13251.txt new file mode 100644 index 00000000000..ce99d40b7ee --- /dev/null +++ b/.changelog/13251.txt @@ -0,0 +1,15 @@ +```release-note:new-resource +aws_networkmanager_global_network +``` + +```release-note:new-resource +aws_networkmanager_site +``` + +```release-note:new-data-source +aws_networkmanager_global_network +``` + +```release-note:new-data-source +aws_networkmanager_global_networks +``` \ No newline at end of file From c1515d894defc2f1d712b7f613870631342e14f6 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 14:33:23 -0500 Subject: [PATCH 061/229] Sweep Sites. --- internal/service/networkmanager/sweep.go | 79 +++++++++++++++++++++++- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/internal/service/networkmanager/sweep.go b/internal/service/networkmanager/sweep.go index e86428316de..91f5582fc6e 100644 --- a/internal/service/networkmanager/sweep.go +++ b/internal/service/networkmanager/sweep.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" + multierror "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/sweep" @@ -18,9 +19,14 @@ func init() { resource.AddTestSweepers("aws_networkmanager_global_network", &resource.Sweeper{ Name: "aws_networkmanager_global_network", F: sweepGlobalNetworks, - // Dependencies: []string{ - // "aws_networkmanager_site", - // }, + Dependencies: []string{ + "aws_networkmanager_site", + }, + }) + + resource.AddTestSweepers("aws_networkmanager_site", &resource.Sweeper{ + Name: "aws_networkmanager_site", + F: sweepSites, }) } @@ -66,3 +72,70 @@ func sweepGlobalNetworks(region string) error { return nil } + +func sweepSites(region string) error { + client, err := sweep.SharedRegionalSweepClient(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*conns.AWSClient).NetworkManagerConn + input := &networkmanager.DescribeGlobalNetworksInput{} + var sweeperErrs *multierror.Error + sweepResources := make([]*sweep.SweepResource, 0) + + err = conn.DescribeGlobalNetworksPages(input, func(page *networkmanager.DescribeGlobalNetworksOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.GlobalNetworks { + input := &networkmanager.GetSitesInput{ + GlobalNetworkId: v.GlobalNetworkId, + } + + err := conn.GetSitesPages(input, func(page *networkmanager.GetSitesOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.Sites { + r := ResourceSite() + d := r.Data(nil) + d.SetId(aws.StringValue(v.SiteId)) + d.Set("global_network_id", v.GlobalNetworkId) + + sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) + } + + return !lastPage + }) + + if sweep.SkipSweepError(err) { + continue + } + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing Network Manager Sites (%s): %w", region, err)) + } + } + + return !lastPage + }) + + if sweep.SkipSweepError(err) { + log.Printf("[WARN] Skipping Network Manager Site sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing Network Manager Global Networks (%s): %w", region, err)) + } + + err = sweep.SweepOrchestrator(sweepResources) + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error sweeping Network Manager Sites (%s): %w", region, err)) + } + + return sweeperErrs.ErrorOrNil() +} From b0ba5aef19a8e76b7908acb9800deaeee09a365d Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 14:34:09 -0500 Subject: [PATCH 062/229] Retry Site and Global Network deletion. --- .../service/networkmanager/global_network.go | 23 ++++++++++++---- internal/service/networkmanager/site.go | 26 +++++++++++++++---- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/internal/service/networkmanager/global_network.go b/internal/service/networkmanager/global_network.go index 7a20e4576f8..7aa62131199 100644 --- a/internal/service/networkmanager/global_network.go +++ b/internal/service/networkmanager/global_network.go @@ -154,11 +154,20 @@ func resourceGlobalNetworkDelete(ctx context.Context, d *schema.ResourceData, me conn := meta.(*conns.AWSClient).NetworkManagerConn log.Printf("[DEBUG] Deleting Network Manager Global Network: %s", d.Id()) - _, err := tfresource.RetryWhenAWSErrCodeEqualsContext(ctx, globalNetworkValidationExceptionTimeout, func() (interface{}, error) { - return conn.DeleteGlobalNetworkWithContext(ctx, &networkmanager.DeleteGlobalNetworkInput{ - GlobalNetworkId: aws.String(d.Id()), - }) - }, networkmanager.ErrCodeValidationException) + _, err := tfresource.RetryWhenContext(ctx, globalNetworkValidationExceptionTimeout, + func() (interface{}, error) { + return conn.DeleteGlobalNetworkWithContext(ctx, &networkmanager.DeleteGlobalNetworkInput{ + GlobalNetworkId: aws.String(d.Id()), + }) + }, + func(err error) (bool, error) { + if tfawserr.ErrMessageContains(err, networkmanager.ErrCodeValidationException, "cannot be deleted due to existing devices, sites, or links") { + return true, err + } + + return false, err + }, + ) if tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeResourceNotFoundException) { return nil @@ -175,6 +184,10 @@ func resourceGlobalNetworkDelete(ctx context.Context, d *schema.ResourceData, me return nil } +func globalNetworkIDNotFoundError(err error) bool { + return validationExceptionMessageContains(err, networkmanager.ValidationExceptionReasonFieldValidationFailed, "Global network not found") +} + func FindGlobalNetwork(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.DescribeGlobalNetworksInput) (*networkmanager.GlobalNetwork, error) { output, err := FindGlobalNetworks(ctx, conn, input) diff --git a/internal/service/networkmanager/site.go b/internal/service/networkmanager/site.go index 32bc1cc7a64..00a4b91b395 100644 --- a/internal/service/networkmanager/site.go +++ b/internal/service/networkmanager/site.go @@ -10,6 +10,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -226,10 +227,25 @@ func resourceSiteDelete(ctx context.Context, d *schema.ResourceData, meta interf globalNetworkID := d.Get("global_network_id").(string) log.Printf("[DEBUG] Deleting Network Manager Site: %s", d.Id()) - _, err := conn.DeleteSiteWithContext(ctx, &networkmanager.DeleteSiteInput{ - GlobalNetworkId: aws.String(globalNetworkID), - SiteId: aws.String(d.Id()), - }) + _, err := tfresource.RetryWhenContext(ctx, siteValidationExceptionTimeout, + func() (interface{}, error) { + return conn.DeleteSiteWithContext(ctx, &networkmanager.DeleteSiteInput{ + GlobalNetworkId: aws.String(globalNetworkID), + SiteId: aws.String(d.Id()), + }) + }, + func(err error) (bool, error) { + if tfawserr.ErrMessageContains(err, networkmanager.ErrCodeValidationException, "cannot be deleted due to existing association") { + return true, err + } + + return false, err + }, + ) + + if globalNetworkIDNotFoundError(err) || tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeResourceNotFoundException) { + return nil + } if err != nil { return diag.Errorf("error deleting Network Manager Site (%s): %s", d.Id(), err) @@ -279,7 +295,7 @@ func FindSites(ctx context.Context, conn *networkmanager.NetworkManager, input * return !lastPage }) - if validationExceptionMessageContains(err, networkmanager.ValidationExceptionReasonFieldValidationFailed, "Global network not found") { + if globalNetworkIDNotFoundError(err) { return nil, &resource.NotFoundError{ LastError: err, LastRequest: input, From 857fc8db48ec63104402c25b5bcf8f603176ffcd Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 14:45:23 -0500 Subject: [PATCH 063/229] Start work on Site data source. --- internal/service/networkmanager/{ignore => }/site_data_source.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename internal/service/networkmanager/{ignore => }/site_data_source.go (100%) diff --git a/internal/service/networkmanager/ignore/site_data_source.go b/internal/service/networkmanager/site_data_source.go similarity index 100% rename from internal/service/networkmanager/ignore/site_data_source.go rename to internal/service/networkmanager/site_data_source.go From aaebfb57b5ee8db85b430583a7d77b283dda52f0 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 14:54:54 -0500 Subject: [PATCH 064/229] d/aws_networkmanager_site: Modernize. --- .changelog/13251.txt | 4 + internal/provider/provider.go | 1 + .../networkmanager/site_data_source.go | 91 ++++++------------- .../docs/d/networkmanager_site.html.markdown | 13 +-- 4 files changed, 38 insertions(+), 71 deletions(-) diff --git a/.changelog/13251.txt b/.changelog/13251.txt index ce99d40b7ee..eb74a153cfc 100644 --- a/.changelog/13251.txt +++ b/.changelog/13251.txt @@ -12,4 +12,8 @@ aws_networkmanager_global_network ```release-note:new-data-source aws_networkmanager_global_networks +``` + +```release-note:new-data-source +aws_networkmanager_site ``` \ No newline at end of file diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 9e8d71acb8c..4c0567fe5fa 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -715,6 +715,7 @@ func Provider() *schema.Provider { "aws_networkmanager_global_network": networkmanager.DataSourceGlobalNetwork(), "aws_networkmanager_global_networks": networkmanager.DataSourceGlobalNetworks(), + "aws_networkmanager_site": networkmanager.DataSourceSite(), "aws_organizations_delegated_administrators": organizations.DataSourceDelegatedAdministrators(), "aws_organizations_delegated_services": organizations.DataSourceDelegatedServices(), diff --git a/internal/service/networkmanager/site_data_source.go b/internal/service/networkmanager/site_data_source.go index 14063f66980..ca90d4f9531 100644 --- a/internal/service/networkmanager/site_data_source.go +++ b/internal/service/networkmanager/site_data_source.go @@ -1,19 +1,17 @@ package networkmanager import ( - "errors" - "fmt" - "log" + "context" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" ) func DataSourceSite() *schema.Resource { return &schema.Resource{ - Read: DataSourceSiteRead, + ReadWithoutTimeout: dataSourceSiteRead, Schema: map[string]*schema.Schema{ "arn": { @@ -28,10 +26,6 @@ func DataSourceSite() *schema.Resource { Type: schema.TypeString, Required: true, }, - "id": { - Type: schema.TypeString, - Optional: true, - }, "location": { Type: schema.TypeList, Computed: true, @@ -52,72 +46,43 @@ func DataSourceSite() *schema.Resource { }, }, }, - "tags": tagsSchemaComputed(), + "site_id": { + Type: schema.TypeString, + Required: true, + }, + "tags": tftags.TagsSchemaComputed(), }, } } -func DataSourceSiteRead(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn - ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig +func dataSourceSiteRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig - input := &networkmanager.GetSitesInput{ - GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), - } - - if v, ok := d.GetOk("id"); ok { - input.SiteIds = aws.StringSlice([]string{v.(string)}) - } - - log.Printf("[DEBUG] Reading Network Manager Site: %s", input) - output, err := conn.GetSites(input) + globalNetworkID := d.Get("global_network_id").(string) + siteID := d.Get("site_id").(string) + site, err := FindSiteByTwoPartKey(ctx, conn, globalNetworkID, siteID) if err != nil { - return fmt.Errorf("error reading Network Manager Site: %s", err) + return diag.Errorf("error reading Network Manager Site (%s): %s", siteID, err) } - // do filtering here - var filteredSites []*networkmanager.Site - if tags, ok := d.GetOk("tags"); ok { - keyValueTags := keyvaluetags.New(tags.(map[string]interface{})).IgnoreAws() - for _, site := range output.Sites { - tagsMatch := true - if len(keyValueTags) > 0 { - listTags := keyvaluetags.NetworkmanagerKeyValueTags(site.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) - tagsMatch = listTags.ContainsAll(keyValueTags) - } - if tagsMatch { - filteredSites = append(filteredSites, site) - } + d.SetId(siteID) + d.Set("arn", site.SiteArn) + d.Set("description", site.Description) + d.Set("global_network_id", site.GlobalNetworkId) + if site.Location != nil { + if err := d.Set("location", []interface{}{flattenLocation(site.Location)}); err != nil { + return diag.Errorf("error setting location: %s", err) } } else { - filteredSites = output.Sites + d.Set("location", nil) } + d.Set("site_id", site.SiteId) - if output == nil || len(filteredSites) == 0 { - return errors.New("error reading Network Manager Site: no results found") + if err := d.Set("tags", KeyValueTags(site.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return diag.Errorf("error setting tags: %s", err) } - if len(filteredSites) > 1 { - return errors.New("error reading Network Manager Site: more than one result found. Please try a more specific search criteria.") - } - - site := filteredSites[0] - - if site == nil { - return errors.New("error reading Network Manager Site: empty result") - } - - d.Set("description", site.Description) - d.Set("arn", site.SiteArn) - if err := d.Set("location", flattenLocation(site.Location)); err != nil { - return fmt.Errorf("error setting location: %s", err) - } - if err := d.Set("tags", keyvaluetags.NetworkmanagerKeyValueTags(site.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %s", err) - } - - d.SetId(aws.StringValue(site.SiteId)) - return nil } diff --git a/website/docs/d/networkmanager_site.html.markdown b/website/docs/d/networkmanager_site.html.markdown index ec5c239c899..4e20090ac0e 100644 --- a/website/docs/d/networkmanager_site.html.markdown +++ b/website/docs/d/networkmanager_site.html.markdown @@ -1,7 +1,7 @@ --- -subcategory: "Transit Gateway Network Manager" +subcategory: "Network Manager" layout: "aws" -page_title: "AWS: aws_networkmanager_site" +page_title: "AWS: aws_networkmanager_site" description: |- Retrieve information about a site. --- @@ -14,18 +14,15 @@ Retrieve information about a site. ```hcl data " aws_networkmanager_site" "example" { - id = var.global_network_id + global_network_id = var.global_network_id + site_id = var.site_id } ``` ## Argument Reference -* `id` - (Optional) The id of the specific site to retrieve. - * `global_network_id` - (Required) The ID of the Global Network of the site to retrieve. - -* `tags` - (Optional) A map of tags, each pair of which must exactly match - a pair on the desired site. +* `site_id` - (Required) The id of the specific site to retrieve. ## Attributes Reference From 147826bc3e5d993e9728893ef6e37a4954e2c32b Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 14:59:04 -0500 Subject: [PATCH 065/229] Start work on Site data source acceptance tests. --- .../service/networkmanager/{ignore => }/site_data_source_test.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename internal/service/networkmanager/{ignore => }/site_data_source_test.go (100%) diff --git a/internal/service/networkmanager/ignore/site_data_source_test.go b/internal/service/networkmanager/site_data_source_test.go similarity index 100% rename from internal/service/networkmanager/ignore/site_data_source_test.go rename to internal/service/networkmanager/site_data_source_test.go From 97e0f12db8872d581091f1459eed3966e23e66f6 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 15:07:06 -0500 Subject: [PATCH 066/229] d/aws_networkmanager_site: All acceptance tests passing. Acceptance test output: % TF_ACC=1 go test ./internal/service/networkmanager -v -count 1 -parallel 20 -run='TestAccNetworkManagerSiteDataSource_' -timeout 180m === RUN TestAccNetworkManagerSiteDataSource_basic === PAUSE TestAccNetworkManagerSiteDataSource_basic === CONT TestAccNetworkManagerSiteDataSource_basic --- PASS: TestAccNetworkManagerSiteDataSource_basic (23.93s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 27.913s --- .../networkmanager/site_data_source_test.go | 66 +++++++------------ 1 file changed, 23 insertions(+), 43 deletions(-) diff --git a/internal/service/networkmanager/site_data_source_test.go b/internal/service/networkmanager/site_data_source_test.go index 9e262e29b29..c532abccadc 100644 --- a/internal/service/networkmanager/site_data_source_test.go +++ b/internal/service/networkmanager/site_data_source_test.go @@ -4,82 +4,62 @@ import ( "fmt" "testing" + "github.com/aws/aws-sdk-go/service/networkmanager" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-provider-aws/internal/acctest" ) -func TestAccDataSourceSite_basic(t *testing.T) { +func TestAccNetworkManagerSiteDataSource_basic(t *testing.T) { dataSourceName := "data.aws_networkmanager_site.test" - dataSourceByIdName := "data.aws_networkmanager_site.test_by_id" - dataSourceByTagsName := "data.aws_networkmanager_site.test_by_tags" resourceName := "aws_networkmanager_site.test" - resourceGlobalNetworkName := "aws_networkmanager_global_network.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - acctest.PreCheck(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAwsSiteDestroy, + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, Steps: []resource.TestStep{ { - Config: testAccDataSourceSiteConfig(), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrPair(dataSourceName, "id", resourceName, "id"), + Config: testAccSiteDataSourceConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"), resource.TestCheckResourceAttrPair(dataSourceName, "description", resourceName, "description"), - resource.TestCheckResourceAttrPair(dataSourceName, "global_network_id", resourceGlobalNetworkName, "id"), - resource.TestCheckResourceAttrPair(dataSourceName, "tags.Name", resourceName, "tags.Name"), - resource.TestCheckResourceAttrPair(dataSourceName, "tags.OtherTag", resourceName, "tags.OtherTag"), - resource.TestCheckResourceAttr(dataSourceName, "location.#", "1"), - resource.TestCheckResourceAttr(dataSourceName, "location.0.address", ""), - resource.TestCheckResourceAttr(dataSourceName, "location.0.latitude", "18.0029784"), - resource.TestCheckResourceAttr(dataSourceName, "location.0.longitude", "-76.7897987"), - resource.TestCheckResourceAttrPair(dataSourceByIdName, "id", resourceName, "id"), - resource.TestCheckResourceAttrPair(dataSourceByTagsName, "tags.Name", resourceName, "tags.Name"), + resource.TestCheckResourceAttrPair(dataSourceName, "global_network_id", resourceName, "global_network_id"), + resource.TestCheckResourceAttrPair(dataSourceName, "location.#", resourceName, "location.#"), + resource.TestCheckResourceAttrPair(dataSourceName, "site_id", resourceName, "id"), + resource.TestCheckResourceAttrPair(dataSourceName, "tags.%", resourceName, "tags.%"), ), }, }, }) } -func testAccDataSourceSiteConfig() string { +func testAccSiteDataSourceConfig(rName string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { - description = "test" + tags = { + Name = %[1]q + } } resource "aws_networkmanager_site" "test" { - description = "test" - global_network_id = aws_networkmanager_global_network.test.id + description = "test" + global_network_id = aws_networkmanager_global_network.test.id location { - latitude = "18.0029784" - longitude = "-76.7897987" + latitude = "18.0029784" + longitude = "-76.7897987" } tags = { - Name = "terraform-testacc-site-%d" - OtherTag = "some-value" + Name = %[1]q } } data "aws_networkmanager_site" "test" { - global_network_id = aws_networkmanager_site.test.global_network_id -} - -data "aws_networkmanager_site" "test_by_id" { global_network_id = aws_networkmanager_global_network.test.id - id = aws_networkmanager_site.test.id -} - -data "aws_networkmanager_site" "test_by_tags" { - global_network_id = aws_networkmanager_global_network.test.id - - tags = { - Name = aws_networkmanager_site.test.tags["Name"] - } + site_id = aws_networkmanager_site.test.id } -`, sdkacctest.RandInt()) +`, rName) } From 4a5a062ba12d4dcd547d46bac9bf8b1637a039eb Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 15:24:37 -0500 Subject: [PATCH 067/229] d/aws_networkmanager_sites: New data source. Acceptance test output: % TF_ACC=1 go test ./internal/service/networkmanager -v -count 1 -parallel 20 -run='TestAccNetworkManagerSitesDataSource_' -timeout 180m === RUN TestAccNetworkManagerSitesDataSource_basic === PAUSE TestAccNetworkManagerSitesDataSource_basic === CONT TestAccNetworkManagerSitesDataSource_basic --- PASS: TestAccNetworkManagerSitesDataSource_basic (24.83s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 28.708s --- .changelog/13251.txt | 4 ++ internal/provider/provider.go | 1 + .../networkmanager/sites_data_source.go | 62 ++++++++++++++++ .../networkmanager/sites_data_source_test.go | 70 +++++++++++++++++++ .../docs/d/networkmanager_sites.html.markdown | 34 +++++++++ 5 files changed, 171 insertions(+) create mode 100644 internal/service/networkmanager/sites_data_source.go create mode 100644 internal/service/networkmanager/sites_data_source_test.go create mode 100644 website/docs/d/networkmanager_sites.html.markdown diff --git a/.changelog/13251.txt b/.changelog/13251.txt index eb74a153cfc..b15669e0318 100644 --- a/.changelog/13251.txt +++ b/.changelog/13251.txt @@ -16,4 +16,8 @@ aws_networkmanager_global_networks ```release-note:new-data-source aws_networkmanager_site +``` + +```release-note:new-data-source +aws_networkmanager_sites ``` \ No newline at end of file diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 4c0567fe5fa..47d93e13a08 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -716,6 +716,7 @@ func Provider() *schema.Provider { "aws_networkmanager_global_network": networkmanager.DataSourceGlobalNetwork(), "aws_networkmanager_global_networks": networkmanager.DataSourceGlobalNetworks(), "aws_networkmanager_site": networkmanager.DataSourceSite(), + "aws_networkmanager_sites": networkmanager.DataSourceSites(), "aws_organizations_delegated_administrators": organizations.DataSourceDelegatedAdministrators(), "aws_organizations_delegated_services": organizations.DataSourceDelegatedServices(), diff --git a/internal/service/networkmanager/sites_data_source.go b/internal/service/networkmanager/sites_data_source.go new file mode 100644 index 00000000000..9f2b1f5ed91 --- /dev/null +++ b/internal/service/networkmanager/sites_data_source.go @@ -0,0 +1,62 @@ +package networkmanager + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" +) + +func DataSourceSites() *schema.Resource { + return &schema.Resource{ + ReadWithoutTimeout: dataSourceSitesRead, + + Schema: map[string]*schema.Schema{ + "global_network_id": { + Type: schema.TypeString, + Required: true, + }, + "ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "tags": tftags.TagsSchema(), + }, + } +} + +func dataSourceSitesRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig + tagsToMatch := tftags.New(d.Get("tags").(map[string]interface{})).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) + + output, err := FindSites(ctx, conn, &networkmanager.GetSitesInput{ + GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), + }) + + if err != nil { + return diag.Errorf("error listing Network Manager Sites: %s", err) + } + + var siteIDs []string + + for _, v := range output { + if len(tagsToMatch) > 0 { + if !KeyValueTags(v.Tags).ContainsAll(tagsToMatch) { + continue + } + } + + siteIDs = append(siteIDs, aws.StringValue(v.SiteId)) + } + + d.SetId(meta.(*conns.AWSClient).Region) + d.Set("ids", siteIDs) + + return nil +} diff --git a/internal/service/networkmanager/sites_data_source_test.go b/internal/service/networkmanager/sites_data_source_test.go new file mode 100644 index 00000000000..4f91e04129a --- /dev/null +++ b/internal/service/networkmanager/sites_data_source_test.go @@ -0,0 +1,70 @@ +package networkmanager_test + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/networkmanager" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" +) + +func TestAccNetworkManagerSitesDataSource_basic(t *testing.T) { + dataSourceAllName := "data.aws_networkmanager_sites.all" + dataSourceByTagsName := "data.aws_networkmanager_sites.by_tags" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccSitesDataSourceConfig(rName), + Check: resource.ComposeTestCheckFunc( + acctest.CheckResourceAttrGreaterThanValue(dataSourceAllName, "ids.#", "1"), + resource.TestCheckResourceAttr(dataSourceByTagsName, "ids.#", "1"), + ), + }, + }, + }) +} + +func testAccSitesDataSourceConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test1" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test2" { + global_network_id = aws_networkmanager_global_network.test.id +} + +data "aws_networkmanager_sites" "all" { + global_network_id = aws_networkmanager_global_network.test.id + + depends_on = [aws_networkmanager_site.test1, aws_networkmanager_site.test2] +} + +data "aws_networkmanager_sites" "by_tags" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } + + depends_on = [aws_networkmanager_site.test1, aws_networkmanager_site.test2] +} +`, rName) +} diff --git a/website/docs/d/networkmanager_sites.html.markdown b/website/docs/d/networkmanager_sites.html.markdown new file mode 100644 index 00000000000..936ce6a718a --- /dev/null +++ b/website/docs/d/networkmanager_sites.html.markdown @@ -0,0 +1,34 @@ +--- +subcategory: "Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_sites" +description: |- + Retrieve information about sites. +--- + +# Data Source: aws_networkmanager_sites + +Retrieve information about sites. + +## Example Usage + +```hcl +data "aws_networkmanager_sites" "example" { + global_network_id = var.global_network_id + + tags = { + Env = "test" + } +} +``` + +## Argument Reference + +* `global_network_id` - (Required) The ID of the Global Network of the sites to retrieve. +* `tags` - (Optional) Restricts the list to the sites with these tags. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `ids` - The IDs of the sites. From 24d257c4f28cee5f79b9b2e73f947f7acabc4c8f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 15:28:30 -0500 Subject: [PATCH 068/229] Start work on Device resource. --- internal/service/networkmanager/{ignore => }/device.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename internal/service/networkmanager/{ignore => }/device.go (100%) diff --git a/internal/service/networkmanager/ignore/device.go b/internal/service/networkmanager/device.go similarity index 100% rename from internal/service/networkmanager/ignore/device.go rename to internal/service/networkmanager/device.go From 046275fc6e197a8dc69f2d5e1fb1720da1c295e2 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 16:10:00 -0500 Subject: [PATCH 069/229] r/aws_networkmanager_device: Modernize resource. --- .changelog/13251.txt | 4 + internal/service/networkmanager/device.go | 366 +++++++++++++--------- 2 files changed, 229 insertions(+), 141 deletions(-) diff --git a/.changelog/13251.txt b/.changelog/13251.txt index b15669e0318..6c087cb2f61 100644 --- a/.changelog/13251.txt +++ b/.changelog/13251.txt @@ -6,6 +6,10 @@ aws_networkmanager_global_network aws_networkmanager_site ``` +```release-note:new-resource +aws_networkmanager_device +``` + ```release-note:new-data-source aws_networkmanager_global_network ``` diff --git a/internal/service/networkmanager/device.go b/internal/service/networkmanager/device.go index 7e6ce8214d8..96d531a7263 100644 --- a/internal/service/networkmanager/device.go +++ b/internal/service/networkmanager/device.go @@ -1,6 +1,7 @@ package networkmanager import ( + "context" "fmt" "log" "strings" @@ -9,21 +10,25 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" - "github.com/terraform-providers/terraform-provider-aws/internal/keyvaluetags" + "github.com/hashicorp/terraform-provider-aws/internal/verify" ) func ResourceDevice() *schema.Resource { return &schema.Resource{ - Create: ResourceDeviceCreate, - Read: ResourceDeviceRead, - Update: ResourceDeviceUpdate, - Delete: ResourceDeviceDelete, + CreateWithoutTimeout: resourceDeviceCreate, + ReadWithoutTimeout: resourceDeviceRead, + UpdateWithoutTimeout: resourceDeviceUpdate, + DeleteWithoutTimeout: resourceDeviceDelete, + Importer: &schema.ResourceImporter{ - State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { d.Set("arn", d.Id()) idErr := fmt.Errorf("Expected ID in format of arn:aws:networkmanager::ACCOUNTID:device/GLOBALNETWORKID/DEVICEID and provided: %s", d.Id()) @@ -45,6 +50,14 @@ func ResourceDevice() *schema.Resource { }, }, + CustomizeDiff: verify.SetTagsDiff, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Update: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + Schema: map[string]*schema.Schema{ "arn": { Type: schema.TypeString, @@ -92,7 +105,8 @@ func ResourceDevice() *schema.Resource { Type: schema.TypeString, Optional: true, }, - "tags": tagsSchema(), + "tags": tftags.TagsSchema(), + "tags_all": tftags.TagsSchemaComputed(), "type": { Type: schema.TypeString, Optional: true, @@ -105,101 +119,121 @@ func ResourceDevice() *schema.Resource { } } -func ResourceDeviceCreate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn +func resourceDeviceCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{}))) + + globalNetworkID := d.Get("global_network_id").(string) input := &networkmanager.CreateDeviceInput{ - Description: aws.String(d.Get("description").(string)), - GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), - Location: expandLocation(d.Get("location").([]interface{})), - Model: aws.String(d.Get("model").(string)), - SerialNumber: aws.String(d.Get("serial_number").(string)), - SiteId: aws.String(d.Get("site_id").(string)), - Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().NetworkmanagerTags(), - Type: aws.String(d.Get("type").(string)), - Vendor: aws.String(d.Get("vendor").(string)), + GlobalNetworkId: aws.String(globalNetworkID), } - log.Printf("[DEBUG] Creating Network Manager Device: %s", input) - - output, err := conn.CreateDevice(input) - if err != nil { - return fmt.Errorf("error creating Network Manager Device: %s", err) + if v, ok := d.GetOk("description"); ok { + input.Description = aws.String(v.(string)) } - d.SetId(aws.StringValue(output.Device.DeviceId)) + if v, ok := d.GetOk("location"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.Location = expandLocation(v.([]interface{})[0].(map[string]interface{})) + } - stateConf := &resource.StateChangeConf{ - Pending: []string{networkmanager.DeviceStatePending}, - Target: []string{networkmanager.DeviceStateAvailable}, - Refresh: networkmanagerDeviceRefreshFunc(conn, aws.StringValue(output.Device.GlobalNetworkId), aws.StringValue(output.Device.DeviceId)), - Timeout: 10 * time.Minute, + if v, ok := d.GetOk("model"); ok { + input.Model = aws.String(v.(string)) } - _, err = stateConf.WaitForState() - if err != nil { - return fmt.Errorf("error waiting for Network Manager Device (%s) availability: %s", d.Id(), err) + if v, ok := d.GetOk("serial_number"); ok { + input.SerialNumber = aws.String(v.(string)) } - return ResourceDeviceRead(d, meta) -} + if v, ok := d.GetOk("site_id"); ok { + input.SiteId = aws.String(v.(string)) + } -func ResourceDeviceRead(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn - ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + if v, ok := d.GetOk("type"); ok { + input.Type = aws.String(v.(string)) + } - device, err := networkmanagerDescribeDevice(conn, d.Get("global_network_id").(string), d.Id()) + if v, ok := d.GetOk("vendor"); ok { + input.Vendor = aws.String(v.(string)) + } - if tfawserr.ErrCodeEquals(err, "InvalidDeviceID.NotFound", "") { - log.Printf("[WARN] Network Manager Device (%s) not found, removing from state", d.Id()) - d.SetId("") - return nil + if len(tags) > 0 { + input.Tags = Tags(tags.IgnoreAWS()) } + log.Printf("[DEBUG] Creating Network Manager Device: %s", input) + output, err := conn.CreateDeviceWithContext(ctx, input) + if err != nil { - return fmt.Errorf("error reading Network Manager Device: %s", err) + return diag.Errorf("error creating Network Manager Device: %s", err) } - if device == nil { - log.Printf("[WARN] Network Manager Device (%s) not found, removing from state", d.Id()) - d.SetId("") - return nil + d.SetId(aws.StringValue(output.Device.DeviceId)) + + if _, err := waitDeviceCreated(ctx, conn, globalNetworkID, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { + return diag.Errorf("error waiting for Network Manager Device (%s) create: %s", d.Id(), err) } - if aws.StringValue(device.State) == networkmanager.DeviceStateDeleting { - log.Printf("[WARN] Network Manager Device (%s) in deleted state (%s), removing from state", d.Id(), aws.StringValue(device.State)) + return resourceDeviceRead(ctx, d, meta) +} + +func resourceDeviceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig + + globalNetworkID := d.Get("global_network_id").(string) + device, err := FindDeviceByTwoPartKey(ctx, conn, globalNetworkID, d.Id()) + + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Network Manager Device %s not found, removing from state", d.Id()) d.SetId("") return nil } + if err != nil { + return diag.Errorf("error reading Network Manager Device (%s): %s", d.Id(), err) + } + d.Set("arn", device.DeviceArn) d.Set("description", device.Description) + if device.Location != nil { + if err := d.Set("location", []interface{}{flattenLocation(device.Location)}); err != nil { + return diag.Errorf("error setting location: %s", err) + } + } else { + d.Set("location", nil) + } d.Set("model", device.Model) d.Set("serial_number", device.SerialNumber) d.Set("site_id", device.SiteId) d.Set("type", device.Type) d.Set("vendor", device.Vendor) - if err := d.Set("location", flattenLocation(device.Location)); err != nil { - return fmt.Errorf("error setting location: %s", err) + tags := KeyValueTags(device.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return diag.Errorf("error setting tags: %s", err) } - if err := d.Set("tags", keyvaluetags.NetworkmanagerKeyValueTags(device.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %s", err) + if err := d.Set("tags_all", tags.Map()); err != nil { + return diag.Errorf("error setting tags_all: %s", err) } return nil } -func ResourceDeviceUpdate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn +func resourceDeviceUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn - if d.HasChanges("description", "location", "model", "serial_number", "site_id", "type", "vendor") { - request := &networkmanager.UpdateDeviceInput{ + if d.HasChangesExcept("tags", "tags_all") { + globalNetworkID := d.Get("global_network_id").(string) + input := &networkmanager.UpdateDeviceInput{ Description: aws.String(d.Get("description").(string)), DeviceId: aws.String(d.Id()), - GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), - Location: expandLocation(d.Get("location").([]interface{})), + GlobalNetworkId: aws.String(globalNetworkID), Model: aws.String(d.Get("model").(string)), SerialNumber: aws.String(d.Get("serial_number").(string)), SiteId: aws.String(d.Get("site_id").(string)), @@ -207,145 +241,195 @@ func ResourceDeviceUpdate(d *schema.ResourceData, meta interface{}) error { Vendor: aws.String(d.Get("vendor").(string)), } - _, err := conn.UpdateDevice(request) + if v, ok := d.GetOk("location"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.Location = expandLocation(v.([]interface{})[0].(map[string]interface{})) + } + + log.Printf("[DEBUG] Updating Network Manager Device: %s", input) + _, err := conn.UpdateDeviceWithContext(ctx, input) + if err != nil { - return fmt.Errorf("Failure updating Network Manager Device (%s): %s", d.Id(), err) + return diag.Errorf("error updating Network Manager Device (%s): %s", d.Id(), err) + } + + if _, err := waitDeviceUpdated(ctx, conn, globalNetworkID, d.Id(), d.Timeout(schema.TimeoutUpdate)); err != nil { + return diag.Errorf("error waiting for Network Manager Device (%s) update: %s", d.Id(), err) } } - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") - if err := keyvaluetags.NetworkmanagerUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { - return fmt.Errorf("error updating Network Manager Device (%s) tags: %s", d.Id(), err) + if err := UpdateTags(conn, d.Get("arn").(string), o, n); err != nil { + return diag.Errorf("error updating Network Manager Device (%s) tags: %s", d.Id(), err) } } - return nil + return resourceDeviceRead(ctx, d, meta) } -func ResourceDeviceDelete(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn +func resourceDeviceDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + globalNetworkID := d.Get("global_network_id").(string) - input := &networkmanager.DeleteDeviceInput{ - GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), + log.Printf("[DEBUG] Deleting Network Manager Device: %s", d.Id()) + _, err := conn.DeleteDeviceWithContext(ctx, &networkmanager.DeleteDeviceInput{ + GlobalNetworkId: aws.String(globalNetworkID), DeviceId: aws.String(d.Id()), + }) + + if globalNetworkIDNotFoundError(err) || tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeResourceNotFoundException) { + return nil + } + + if err != nil { + return diag.Errorf("error deleting Network Manager Device (%s): %s", d.Id(), err) } - log.Printf("[DEBUG] Deleting Network Manager Device (%s): %s", d.Id(), input) - err := resource.Retry(2*time.Minute, func() *resource.RetryError { - _, err := conn.DeleteDevice(input) + if _, err := waitDeviceDeleted(ctx, conn, globalNetworkID, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil { + return diag.Errorf("error waiting for Network Manager Device (%s) delete: %s", d.Id(), err) + } - if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Device Associations") { - return resource.RetryableError(err) - } + return nil +} + +func FindDevice(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.GetDevicesInput) (*networkmanager.Device, error) { + output, err := FindDevices(ctx, conn, input) + + if err != nil { + return nil, err + } + + if len(output) == 0 || output[0] == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } - if tfawserr.ErrMessageContains(err, "IncorrectState", "has non-deleted Device") { - return resource.RetryableError(err) + return output[0], nil +} + +func FindDevices(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.GetDevicesInput) ([]*networkmanager.Device, error) { + var output []*networkmanager.Device + + err := conn.GetDevicesPagesWithContext(ctx, input, func(page *networkmanager.GetDevicesOutput, lastPage bool) bool { + if page == nil { + return !lastPage } - if err != nil { - return resource.NonRetryableError(err) + for _, v := range page.Devices { + if v == nil { + continue + } + + output = append(output, v) } - return nil + return !lastPage }) - if tfresource.TimedOut(err) { - _, err = conn.DeleteDevice(input) + if globalNetworkIDNotFoundError(err) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } } - if tfawserr.ErrCodeEquals(err, "InvalidDeviceID.NotFound", "") { - return nil + if err != nil { + return nil, err + } + + return output, nil +} + +func FindDeviceByTwoPartKey(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, deviceID string) (*networkmanager.Device, error) { + input := &networkmanager.GetDevicesInput{ + DeviceIds: aws.StringSlice([]string{deviceID}), + GlobalNetworkId: aws.String(globalNetworkID), } + output, err := FindDevice(ctx, conn, input) + if err != nil { - return fmt.Errorf("error deleting Network Manager Device: %s", err) + return nil, err } - if err := waitForDeviceDeletion(conn, d.Get("global_network_id").(string), d.Id()); err != nil { - return fmt.Errorf("error waiting for Network Manager Device (%s) deletion: %s", d.Id(), err) + // Eventual consistency check. + if aws.StringValue(output.GlobalNetworkId) != globalNetworkID || aws.StringValue(output.DeviceId) != deviceID { + return nil, &resource.NotFoundError{ + LastRequest: input, + } } - return nil + return output, nil } -func networkmanagerDeviceRefreshFunc(conn *networkmanager.NetworkManager, globalNetworkID, deviceID string) resource.StateRefreshFunc { +func statusDeviceState(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, deviceID string) resource.StateRefreshFunc { return func() (interface{}, string, error) { - device, err := networkmanagerDescribeDevice(conn, globalNetworkID, deviceID) + output, err := FindDeviceByTwoPartKey(ctx, conn, globalNetworkID, deviceID) - if tfawserr.ErrCodeEquals(err, "InvalidDeviceID.NotFound", "") { - return nil, "DELETED", nil + if tfresource.NotFound(err) { + return nil, "", nil } if err != nil { - return nil, "", fmt.Errorf("error reading Network Manager Device (%s): %s", deviceID, err) + return nil, "", err } - if device == nil { - return nil, "DELETED", nil - } - - return device, aws.StringValue(device.State), nil + return output, aws.StringValue(output.State), nil } } -func networkmanagerDescribeDevice(conn *networkmanager.NetworkManager, globalNetworkID, deviceID string) (*networkmanager.Device, error) { - input := &networkmanager.GetDevicesInput{ - GlobalNetworkId: aws.String(globalNetworkID), - DeviceIds: []*string{aws.String(deviceID)}, +func waitDeviceCreated(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, deviceID string, timeout time.Duration) (*networkmanager.Device, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.DeviceStatePending}, + Target: []string{networkmanager.DeviceStateAvailable}, + Timeout: timeout, + Refresh: statusDeviceState(ctx, conn, globalNetworkID, deviceID), } - log.Printf("[DEBUG] Reading Network Manager Device (%s): %s", deviceID, input) - for { - output, err := conn.GetDevices(input) - - if err != nil { - return nil, err - } + outputRaw, err := stateConf.WaitForStateContext(ctx) - if output == nil || len(output.Devices) == 0 { - return nil, nil - } + if output, ok := outputRaw.(*networkmanager.Device); ok { + return output, err + } - for _, device := range output.Devices { - if device == nil { - continue - } + return nil, err +} - if aws.StringValue(device.DeviceId) == deviceID { - return device, nil - } - } +func waitDeviceDeleted(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, deviceID string, timeout time.Duration) (*networkmanager.Device, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.DeviceStateDeleting}, + Target: []string{}, + Timeout: timeout, + Refresh: statusDeviceState(ctx, conn, globalNetworkID, deviceID), + } - if aws.StringValue(output.NextToken) == "" { - break - } + outputRaw, err := stateConf.WaitForStateContext(ctx) - input.NextToken = output.NextToken + if output, ok := outputRaw.(*networkmanager.Device); ok { + return output, err } - return nil, nil + return nil, err } -func waitForNetworkManagerDeviceDeletion(conn *networkmanager.NetworkManager, globalNetworkID, deviceID string) error { +func waitDeviceUpdated(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, deviceID string, timeout time.Duration) (*networkmanager.Device, error) { stateConf := &resource.StateChangeConf{ - Pending: []string{ - networkmanager.DeviceStateAvailable, - networkmanager.DeviceStateDeleting, - }, - Target: []string{""}, - Refresh: networkmanagerDeviceRefreshFunc(conn, globalNetworkID, deviceID), - Timeout: 10 * time.Minute, - NotFoundChecks: 1, + Pending: []string{networkmanager.DeviceStateUpdating}, + Target: []string{networkmanager.DeviceStateAvailable}, + Timeout: timeout, + Refresh: statusDeviceState(ctx, conn, globalNetworkID, deviceID), } - log.Printf("[DEBUG] Waiting for Network Manager Device (%s) deletion", deviceID) - _, err := stateConf.WaitForState() + outputRaw, err := stateConf.WaitForStateContext(ctx) - if tfresource.NotFound(err) { - return nil + if output, ok := outputRaw.(*networkmanager.Device); ok { + return output, err } - return err + return nil, err } From 06d42ad7cd72d467875c4bdeceb91a9f8854dd8e Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 16:14:04 -0500 Subject: [PATCH 070/229] r/aws_networkmanager_site: Simplify update. --- internal/service/networkmanager/site.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/internal/service/networkmanager/site.go b/internal/service/networkmanager/site.go index 00a4b91b395..482f35fff24 100644 --- a/internal/service/networkmanager/site.go +++ b/internal/service/networkmanager/site.go @@ -183,17 +183,14 @@ func resourceSiteRead(ctx context.Context, d *schema.ResourceData, meta interfac func resourceSiteUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*conns.AWSClient).NetworkManagerConn - if d.HasChanges("description", "location") { + if d.HasChangesExcept("tags", "tags_all") { globalNetworkID := d.Get("global_network_id").(string) input := &networkmanager.UpdateSiteInput{ + Description: aws.String(d.Get("description").(string)), GlobalNetworkId: aws.String(globalNetworkID), SiteId: aws.String(d.Id()), } - if v, ok := d.GetOk("description"); ok { - input.Description = aws.String(v.(string)) - } - if v, ok := d.GetOk("location"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { input.Location = expandLocation(v.([]interface{})[0].(map[string]interface{})) } From c3ae74ac46739c22cc3154695b265e42f390c818 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 16:14:18 -0500 Subject: [PATCH 071/229] r/aws_networkmanager_global_network: Simplify update. --- internal/service/networkmanager/global_network.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/networkmanager/global_network.go b/internal/service/networkmanager/global_network.go index 7aa62131199..01586e29efc 100644 --- a/internal/service/networkmanager/global_network.go +++ b/internal/service/networkmanager/global_network.go @@ -121,7 +121,7 @@ func resourceGlobalNetworkRead(ctx context.Context, d *schema.ResourceData, meta func resourceGlobalNetworkUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*conns.AWSClient).NetworkManagerConn - if d.HasChange("description") { + if d.HasChangesExcept("tags", "tags_all") { input := &networkmanager.UpdateGlobalNetworkInput{ Description: aws.String(d.Get("description").(string)), GlobalNetworkId: aws.String(d.Id()), From 0cbb6c4df05cdb4e19d0d7bcd6b61e576c5b62b7 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 16:16:06 -0500 Subject: [PATCH 072/229] Start work on Device acceptance tests. --- internal/service/networkmanager/{ignore => }/device_test.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename internal/service/networkmanager/{ignore => }/device_test.go (100%) diff --git a/internal/service/networkmanager/ignore/device_test.go b/internal/service/networkmanager/device_test.go similarity index 100% rename from internal/service/networkmanager/ignore/device_test.go rename to internal/service/networkmanager/device_test.go From b29b31b6cb30bdec59cf64c2320677e82f7e6601 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 16:17:04 -0500 Subject: [PATCH 073/229] Add 'aws_networkmanager_device' resource. --- internal/provider/provider.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 47d93e13a08..67eaf26af9b 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1582,6 +1582,7 @@ func Provider() *schema.Provider { "aws_networkfirewall_resource_policy": networkfirewall.ResourceResourcePolicy(), "aws_networkfirewall_rule_group": networkfirewall.ResourceRuleGroup(), + "aws_networkmanager_device": networkmanager.ResourceDevice(), "aws_networkmanager_global_network": networkmanager.ResourceGlobalNetwork(), "aws_networkmanager_site": networkmanager.ResourceSite(), From f651655cce8591953e69487e8696575a3a6325b6 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 16:26:44 -0500 Subject: [PATCH 074/229] r/aws_networkmanager_device: Basic acceptance test. Acceptance test output: % TF_ACC=1 go test ./internal/service/networkmanager -v -count 1 -parallel 20 -run='TestAccNetworkManagerDevice_' -timeout 180m === RUN TestAccNetworkManagerDevice_basic === PAUSE TestAccNetworkManagerDevice_basic === CONT TestAccNetworkManagerDevice_basic --- PASS: TestAccNetworkManagerDevice_basic (22.63s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 27.050s --- internal/service/networkmanager/device.go | 21 +- .../service/networkmanager/device_test.go | 262 +++--------------- 2 files changed, 56 insertions(+), 227 deletions(-) diff --git a/internal/service/networkmanager/device.go b/internal/service/networkmanager/device.go index 96d531a7263..8d8221b2247 100644 --- a/internal/service/networkmanager/device.go +++ b/internal/service/networkmanager/device.go @@ -29,22 +29,21 @@ func ResourceDevice() *schema.Resource { Importer: &schema.ResourceImporter{ StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - d.Set("arn", d.Id()) + parsedARN, err := arn.Parse(d.Id()) - idErr := fmt.Errorf("Expected ID in format of arn:aws:networkmanager::ACCOUNTID:device/GLOBALNETWORKID/DEVICEID and provided: %s", d.Id()) - - resARN, err := arn.Parse(d.Id()) if err != nil { - return nil, idErr + return nil, fmt.Errorf("error parsing ARN (%s): %w", d.Id(), err) } - identifiers := strings.TrimPrefix(resARN.Resource, "device/") - identifierParts := strings.Split(identifiers, "/") - if len(identifierParts) != 2 { - return nil, idErr + // See https://docs.aws.amazon.com/service-authorization/latest/reference/list_networkmanager.html#networkmanager-resources-for-iam-policies. + resourceParts := strings.Split(parsedARN.Resource, "/") + + if actual, expected := len(resourceParts), 3; actual < expected { + return nil, fmt.Errorf("expected at least %d resource parts in ARN (%s), got: %d", expected, d.Id(), actual) } - d.SetId(identifierParts[1]) - d.Set("global_network_id", identifierParts[0]) + + d.SetId(resourceParts[2]) + d.Set("global_network_id", resourceParts[1]) return []*schema.ResourceData{d}, nil }, diff --git a/internal/service/networkmanager/device_test.go b/internal/service/networkmanager/device_test.go index 180b033acf2..9c6e160028b 100644 --- a/internal/service/networkmanager/device_test.go +++ b/internal/service/networkmanager/device_test.go @@ -1,103 +1,43 @@ -package networkmanager +package networkmanager_test import ( + "context" "fmt" - "log" "testing" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" - "github.com/hashicorp/go-multierror" + 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" "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tfnetworkmanager "github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -func init() { - resource.AddTestSweepers("aws_networkmanager_device", &resource.Sweeper{ - Name: "aws_networkmanager_device", - F: testSweepDevice, - }) -} - -func testSweepDevice(region string) error { - client, err := sharedClientForRegion(region) - if err != nil { - return fmt.Errorf("error getting client: %s", err) - } - conn := client.(*AWSClient).networkmanagerconn - var sweeperErrs *multierror.Error - - err = conn.GetDevicesPages(&networkmanager.GetDevicesInput{}, - func(page *networkmanager.GetDevicesOutput, lastPage bool) bool { - for _, device := range page.Devices { - input := &networkmanager.DeleteDeviceInput{ - GlobalNetworkId: device.GlobalNetworkId, - DeviceId: device.DeviceId, - } - id := aws.StringValue(device.DeviceId) - globalNetworkID := aws.StringValue(device.GlobalNetworkId) - - log.Printf("[INFO] Deleting Network Manager Device: %s", id) - _, err := conn.DeleteDevice(input) - - if tfawserr.ErrCodeEquals(err, "InvalidDeviceID.NotFound", "") { - continue - } - - if err != nil { - sweeperErr := fmt.Errorf("failed to delete Network Manager Device %s: %s", id, err) - log.Printf("[ERROR] %s", sweeperErr) - sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) - continue - } - - if err := waitForDeviceDeletion(conn, globalNetworkID, id); err != nil { - sweeperErr := fmt.Errorf("error waiting for Network Manager Device (%s) deletion: %s", id, err) - log.Printf("[ERROR] %s", sweeperErr) - sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) - continue - } - } - return !lastPage - }) - if testSweepSkipSweepError(err) { - log.Printf("[WARN] Skipping Network Manager Device sweep for %s: %s", region, err) - return nil - } - - if err != nil { - return fmt.Errorf("Error retrieving Network Manager Devices: %s", err) - } - - return sweeperErrs.ErrorOrNil() -} - -func TestAccDevice_basic(t *testing.T) { +func TestAccNetworkManagerDevice_basic(t *testing.T) { resourceName := "aws_networkmanager_device.test" - siteResourceName := "aws_networkmanager_site.test" - site2ResourceName := "aws_networkmanager_site.test2" - gloablNetworkResourceName := "aws_networkmanager_global_network.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAwsDeviceDestroy, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckDeviceDestroy, Steps: []resource.TestStep{ { - Config: testAccDeviceConfig("test"), - Check: resource.ComposeTestCheckFunc( - testAccCheckAwsDeviceExists(resourceName), + Config: testAccDeviceConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckDeviceExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetworkResourceName, "id"), - resource.TestCheckResourceAttrPair(resourceName, "site_id", siteResourceName, "id"), - resource.TestCheckResourceAttr(resourceName, "description", "test"), - resource.TestCheckResourceAttr(resourceName, "model", "abc"), - resource.TestCheckResourceAttr(resourceName, "serial_number", "123"), - resource.TestCheckResourceAttr(resourceName, "type", "office device"), - resource.TestCheckResourceAttr(resourceName, "vendor", "company"), + resource.TestCheckResourceAttr(resourceName, "description", ""), resource.TestCheckResourceAttr(resourceName, "location.#", "0"), + resource.TestCheckResourceAttr(resourceName, "model", ""), + resource.TestCheckResourceAttr(resourceName, "serial_number", ""), + resource.TestCheckResourceAttr(resourceName, "site_id", ""), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "type", ""), + resource.TestCheckResourceAttr(resourceName, "vendor", ""), ), }, { @@ -106,28 +46,11 @@ func TestAccDevice_basic(t *testing.T) { ImportStateIdFunc: testAccDeviceImportStateIdFunc(resourceName), ImportStateVerify: true, }, - { - Config: testAccDeviceConfig_Update("test updated", "def", "456", "home device", "othercompany", "18.0029784", "-76.7897987"), - Check: resource.ComposeTestCheckFunc( - testAccCheckAwsDeviceExists(resourceName), - resource.TestCheckResourceAttrSet(resourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetworkResourceName, "id"), - resource.TestCheckResourceAttrPair(resourceName, "site_id", site2ResourceName, "id"), - resource.TestCheckResourceAttr(resourceName, "description", "test updated"), - resource.TestCheckResourceAttr(resourceName, "model", "def"), - resource.TestCheckResourceAttr(resourceName, "serial_number", "456"), - resource.TestCheckResourceAttr(resourceName, "type", "home device"), - resource.TestCheckResourceAttr(resourceName, "vendor", "othercompany"), - resource.TestCheckResourceAttr(resourceName, "location.#", "1"), - resource.TestCheckResourceAttr(resourceName, "location.0.address", ""), - resource.TestCheckResourceAttr(resourceName, "location.0.latitude", "18.0029784"), - resource.TestCheckResourceAttr(resourceName, "location.0.longitude", "-76.7897987"), - ), - }, }, }) } +/* func TestAccDevice_tags(t *testing.T) { resourceName := "aws_networkmanager_device.test" description := "test" @@ -174,160 +97,67 @@ func TestAccDevice_tags(t *testing.T) { }, }) } +*/ -func testAccCheckAwsDeviceDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn +func testAccCheckDeviceDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn for _, rs := range s.RootModule().Resources { if rs.Type != "aws_networkmanager_device" { continue } - device, err := networkmanagerDescribeDevice(conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) - if err != nil { - if tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeValidationException, "") { - return nil - } - return err - } + _, err := tfnetworkmanager.FindDeviceByTwoPartKey(context.TODO(), conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) - if device == nil { + if tfresource.NotFound(err) { continue } - return fmt.Errorf("Expected Device to be destroyed, %s found", rs.Primary.ID) + if err != nil { + return err + } + + return fmt.Errorf("Network Manager Device %s still exists", rs.Primary.ID) } return nil } -func testAccCheckAwsDeviceExists(name string) resource.TestCheckFunc { +func testAccCheckDeviceExists(n string) resource.TestCheckFunc { return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[name] + rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not found: %s", name) + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No Network Manager Device ID is set") } - conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn - device, err := networkmanagerDescribeDevice(conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) + _, err := tfnetworkmanager.FindDeviceByTwoPartKey(context.TODO(), conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) if err != nil { return err } - if device == nil { - return fmt.Errorf("Network Manager Device not found") - } - - if aws.StringValue(device.State) != networkmanager.DeviceStateAvailable && aws.StringValue(device.State) != networkmanager.DeviceStatePending { - return fmt.Errorf("Network Manager Device (%s) exists in (%s) state", rs.Primary.ID, aws.StringValue(device.State)) - } - - return err + return nil } } -func testAccDeviceConfig(description string) string { - return fmt.Sprintf(` -resource "aws_networkmanager_global_network" "test" { - description = "test" -} - -resource "aws_networkmanager_site" "test" { - description = "test" - global_network_id = aws_networkmanager_global_network.test.id -} - -resource "aws_networkmanager_device" "test" { - description = %q - global_network_id = aws_networkmanager_global_network.test.id - site_id = aws_networkmanager_site.test.id - model = "abc" - serial_number = "123" - type = "office device" - vendor = "company" -} -`, description) -} - -func testAccDeviceConfigTags1(description, tagKey1, tagValue1 string) string { - return fmt.Sprintf(` -resource "aws_networkmanager_global_network" "test" { - description = "test" -} - -resource "aws_networkmanager_site" "test" { - description = "test" - global_network_id = aws_networkmanager_global_network.test.id -} - -resource "aws_networkmanager_device" "test" { - description = %q - global_network_id = aws_networkmanager_global_network.test.id - site_id = aws_networkmanager_site.test.id - - tags = { - %q = %q - } -} -`, description, tagKey1, tagValue1) -} - -func testAccDeviceConfigTags2(description, tagKey1, tagValue1, tagKey2, tagValue2 string) string { +func testAccDeviceConfig(rName string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { - description = "test" -} - -resource "aws_networkmanager_site" "test" { - description = "test" - global_network_id = aws_networkmanager_global_network.test.id -} - -resource "aws_networkmanager_device" "test" { - description = %q - global_network_id = aws_networkmanager_global_network.test.id - tags = { - %q = %q - %q = %q + Name = %[1]q } } -`, description, tagKey1, tagValue1, tagKey2, tagValue2) -} - -func testAccDeviceConfig_Update(description, model, serial_number, device_type, vendor, latitude, longitude string) string { - return fmt.Sprintf(` -resource "aws_networkmanager_global_network" "test" { - description = "test" -} - -resource "aws_networkmanager_site" "test" { - description = "test" - global_network_id = aws_networkmanager_global_network.test.id -} - -resource "aws_networkmanager_site" "test2" { - description = "test2" - global_network_id = aws_networkmanager_global_network.test.id -} resource "aws_networkmanager_device" "test" { - description = %q - global_network_id = aws_networkmanager_global_network.test.id - site_id = aws_networkmanager_site.test2.id - model = %q - serial_number = %q - type = %q - vendor = %q - - location { - latitude = %q - longitude = %q - } + global_network_id = aws_networkmanager_global_network.test.id } -`, description, model, serial_number, device_type, vendor, latitude, longitude) +`, rName) } func testAccDeviceImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { From 81ff9ee38c0887170f676827d83465f8324b7cb3 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 16:27:17 -0500 Subject: [PATCH 075/229] Not needed. --- .../service/networkmanager/ignore/flex.go | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 internal/service/networkmanager/ignore/flex.go diff --git a/internal/service/networkmanager/ignore/flex.go b/internal/service/networkmanager/ignore/flex.go deleted file mode 100644 index 57875298546..00000000000 --- a/internal/service/networkmanager/ignore/flex.go +++ /dev/null @@ -1,34 +0,0 @@ -package networkmanager - -import ( - "strings" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" -) - -func flattenLocation(location *networkmanager.Location) []interface{} { - if location == nil { - return []interface{}{} - } - m := map[string]interface{}{ - "address": aws.StringValue(location.Address), - "latitude": aws.StringValue(location.Latitude), - "longitude": aws.StringValue(location.Longitude), - } - return []interface{}{m} -} - -func expandLocation(l []interface{}) *networkmanager.Location { - if len(l) == 0 || l[0] == nil { - return nil - } - m := l[0].(map[string]interface{}) - logs := &networkmanager.Location{ - Address: aws.String(m["address"].(string)), - Latitude: aws.String(m["latitude"].(string)), - Longitude: aws.String(m["longitude"].(string)), - } - return logs -} From 3ed1e7a3166215cc32bdb02372fad7730eee3468 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 3 Mar 2022 16:57:13 -0500 Subject: [PATCH 076/229] r/aws_networkmanager_device: Acceptance test. Acceptance test output: % TF_ACC=1 go test ./internal/service/networkmanager -v -count 1 -parallel 20 -run='TestAccNetworkManagerDevice_' -timeout 180m === RUN TestAccNetworkManagerDevice_basic === PAUSE TestAccNetworkManagerDevice_basic === RUN TestAccNetworkManagerDevice_disapears === PAUSE TestAccNetworkManagerDevice_disapears === RUN TestAccNetworkManagerDevice_tags === PAUSE TestAccNetworkManagerDevice_tags === RUN TestAccNetworkManagerDevice_allAttributes === PAUSE TestAccNetworkManagerDevice_allAttributes === CONT TestAccNetworkManagerDevice_basic === CONT TestAccNetworkManagerDevice_tags === CONT TestAccNetworkManagerDevice_disapears === CONT TestAccNetworkManagerDevice_allAttributes --- PASS: TestAccNetworkManagerDevice_disapears (18.25s) --- PASS: TestAccNetworkManagerDevice_allAttributes (37.52s) --- PASS: TestAccNetworkManagerDevice_tags (46.97s) --- PASS: TestAccNetworkManagerDevice_basic (50.54s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 53.965s --- .../service/networkmanager/device_test.go | 233 ++++++++++++++++-- 1 file changed, 218 insertions(+), 15 deletions(-) diff --git a/internal/service/networkmanager/device_test.go b/internal/service/networkmanager/device_test.go index 9c6e160028b..5b6594a6333 100644 --- a/internal/service/networkmanager/device_test.go +++ b/internal/service/networkmanager/device_test.go @@ -50,21 +50,42 @@ func TestAccNetworkManagerDevice_basic(t *testing.T) { }) } -/* -func TestAccDevice_tags(t *testing.T) { +func TestAccNetworkManagerDevice_disapears(t *testing.T) { resourceName := "aws_networkmanager_device.test" - description := "test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAwsDeviceDestroy, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckDeviceDestroy, Steps: []resource.TestStep{ { - Config: testAccDeviceConfigTags1(description, "key1", "value1"), + Config: testAccDeviceConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckDeviceExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfnetworkmanager.ResourceDevice(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccNetworkManagerDevice_tags(t *testing.T) { + resourceName := "aws_networkmanager_device.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckDeviceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDeviceConfigTags1(rName, "key1", "value1"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsDeviceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "description", "test"), + testAccCheckDeviceExists(resourceName), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), ), @@ -76,20 +97,18 @@ func TestAccDevice_tags(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccDeviceConfigTags2(description, "key1", "value1updated", "key2", "value2"), + Config: testAccDeviceConfigTags2(rName, "key1", "value1updated", "key2", "value2"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsDeviceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "description", "test"), + testAccCheckDeviceExists(resourceName), resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), ), }, { - Config: testAccDeviceConfigTags1(description, "key2", "value2"), + Config: testAccDeviceConfigTags1(rName, "key2", "value2"), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsDeviceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "description", "test"), + testAccCheckDeviceExists(resourceName), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), ), @@ -97,7 +116,60 @@ func TestAccDevice_tags(t *testing.T) { }, }) } -*/ + +func TestAccNetworkManagerDevice_allAttributes(t *testing.T) { + resourceName := "aws_networkmanager_device.test" + site1ResourceName := "aws_networkmanager_site.test1" + site2ResourceName := "aws_networkmanager_site.test2" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckDeviceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDeviceAllAttributesConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckDeviceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "description1"), + resource.TestCheckResourceAttr(resourceName, "location.#", "1"), + resource.TestCheckResourceAttr(resourceName, "location.0.address", "Address 1"), + resource.TestCheckResourceAttr(resourceName, "location.0.latitude", "1.1"), + resource.TestCheckResourceAttr(resourceName, "location.0.longitude", "-1.1"), + resource.TestCheckResourceAttr(resourceName, "model", "model1"), + resource.TestCheckResourceAttr(resourceName, "serial_number", "sn1"), + resource.TestCheckResourceAttrPair(resourceName, "site_id", site1ResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "type", "type1"), + resource.TestCheckResourceAttr(resourceName, "vendor", "vendor1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccDeviceImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, + { + Config: testAccDeviceAllAttributesUpdatedConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckDeviceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "description", "description2"), + resource.TestCheckResourceAttr(resourceName, "location.#", "1"), + resource.TestCheckResourceAttr(resourceName, "location.0.address", "Address 2"), + resource.TestCheckResourceAttr(resourceName, "location.0.latitude", "22"), + resource.TestCheckResourceAttr(resourceName, "location.0.longitude", "-22"), + resource.TestCheckResourceAttr(resourceName, "model", "model2"), + resource.TestCheckResourceAttr(resourceName, "serial_number", "sn2"), + resource.TestCheckResourceAttrPair(resourceName, "site_id", site2ResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "type", "type2"), + resource.TestCheckResourceAttr(resourceName, "vendor", "vendor2"), + ), + }, + }, + }) +} func testAccCheckDeviceDestroy(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn @@ -160,6 +232,137 @@ resource "aws_networkmanager_device" "test" { `, rName) } +func testAccDeviceConfigTags1(rName, tagKey1, tagValue1 string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_device" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + %[2]q = %[3]q + } +} +`, rName, tagKey1, tagValue1) +} + +func testAccDeviceConfigTags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_device" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + %[2]q = %[3]q + %[4]q = %[5]q + } +} +`, rName, tagKey1, tagValue1, tagKey2, tagValue2) +} + +func testAccDeviceAllAttributesConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test1" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test2" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_device" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + description = "description1" + model = "model1" + serial_number = "sn1" + site_id = aws_networkmanager_site.test1.id + type = "type1" + vendor = "vendor1" + + location { + address = "Address 1" + latitude = "1.1" + longitude = "-1.1" + } + + tags = { + Name = %[1]q + } +} +`, rName) +} + +func testAccDeviceAllAttributesUpdatedConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test1" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test2" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_device" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + description = "description2" + model = "model2" + serial_number = "sn2" + site_id = aws_networkmanager_site.test2.id + type = "type2" + vendor = "vendor2" + + location { + address = "Address 2" + latitude = "22" + longitude = "-22" + } + + tags = { + Name = %[1]q + } +} +`, rName) +} + func testAccDeviceImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { return func(s *terraform.State) (string, error) { rs, ok := s.RootModule().Resources[resourceName] From 588caf78411514466e43ae9e97b2665f58dfac19 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 07:04:31 -0500 Subject: [PATCH 077/229] Sweep Devices. --- internal/service/networkmanager/sweep.go | 75 ++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/internal/service/networkmanager/sweep.go b/internal/service/networkmanager/sweep.go index 91f5582fc6e..bf4750c0fce 100644 --- a/internal/service/networkmanager/sweep.go +++ b/internal/service/networkmanager/sweep.go @@ -27,6 +27,14 @@ func init() { resource.AddTestSweepers("aws_networkmanager_site", &resource.Sweeper{ Name: "aws_networkmanager_site", F: sweepSites, + Dependencies: []string{ + "aws_networkmanager_device", + }, + }) + + resource.AddTestSweepers("aws_networkmanager_device", &resource.Sweeper{ + Name: "aws_networkmanager_device", + F: sweepDevices, }) } @@ -139,3 +147,70 @@ func sweepSites(region string) error { return sweeperErrs.ErrorOrNil() } + +func sweepDevices(region string) error { + client, err := sweep.SharedRegionalSweepClient(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*conns.AWSClient).NetworkManagerConn + input := &networkmanager.DescribeGlobalNetworksInput{} + var sweeperErrs *multierror.Error + sweepResources := make([]*sweep.SweepResource, 0) + + err = conn.DescribeGlobalNetworksPages(input, func(page *networkmanager.DescribeGlobalNetworksOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.GlobalNetworks { + input := &networkmanager.GetDevicesInput{ + GlobalNetworkId: v.GlobalNetworkId, + } + + err := conn.GetDevicesPages(input, func(page *networkmanager.GetDevicesOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.Devices { + r := ResourceDevice() + d := r.Data(nil) + d.SetId(aws.StringValue(v.DeviceId)) + d.Set("global_network_id", v.GlobalNetworkId) + + sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) + } + + return !lastPage + }) + + if sweep.SkipSweepError(err) { + continue + } + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing Network Manager Devices (%s): %w", region, err)) + } + } + + return !lastPage + }) + + if sweep.SkipSweepError(err) { + log.Printf("[WARN] Skipping Network Manager Device sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing Network Manager Global Networks (%s): %w", region, err)) + } + + err = sweep.SweepOrchestrator(sweepResources) + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error sweeping Network Manager Devices (%s): %w", region, err)) + } + + return sweeperErrs.ErrorOrNil() +} From 9f2cc16761e5613b3adb4f6820fc5a5b5497864f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 07:07:41 -0500 Subject: [PATCH 078/229] Start on Device data source. --- .../service/networkmanager/{ignore => }/device_data_source.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename internal/service/networkmanager/{ignore => }/device_data_source.go (100%) diff --git a/internal/service/networkmanager/ignore/device_data_source.go b/internal/service/networkmanager/device_data_source.go similarity index 100% rename from internal/service/networkmanager/ignore/device_data_source.go rename to internal/service/networkmanager/device_data_source.go From b14be8ce65fc6c4208ceefd1b0c3ddc06fce4a38 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 07:14:34 -0500 Subject: [PATCH 079/229] d/aws_networkmanager_device: Modernize. --- internal/provider/provider.go | 1 + .../networkmanager/device_data_source.go | 95 ++++++------------- .../d/networkmanager_device.html.markdown | 15 ++- 3 files changed, 34 insertions(+), 77 deletions(-) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 67eaf26af9b..d36790f6684 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -713,6 +713,7 @@ func Provider() *schema.Provider { "aws_neptune_engine_version": neptune.DataSourceEngineVersion(), "aws_neptune_orderable_db_instance": neptune.DataSourceOrderableDBInstance(), + "aws_networkmanager_device": networkmanager.DataSourceDevice(), "aws_networkmanager_global_network": networkmanager.DataSourceGlobalNetwork(), "aws_networkmanager_global_networks": networkmanager.DataSourceGlobalNetworks(), "aws_networkmanager_site": networkmanager.DataSourceSite(), diff --git a/internal/service/networkmanager/device_data_source.go b/internal/service/networkmanager/device_data_source.go index 554d9e8518f..acd366c9777 100644 --- a/internal/service/networkmanager/device_data_source.go +++ b/internal/service/networkmanager/device_data_source.go @@ -1,19 +1,17 @@ package networkmanager import ( - "errors" - "fmt" - "log" + "context" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" ) func DataSourceDevice() *schema.Resource { return &schema.Resource{ - Read: DataSourceDeviceRead, + ReadWithoutTimeout: dataSourceDeviceRead, Schema: map[string]*schema.Schema{ "arn": { @@ -24,13 +22,13 @@ func DataSourceDevice() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "global_network_id": { + "device_id": { Type: schema.TypeString, Required: true, }, - "id": { + "global_network_id": { Type: schema.TypeString, - Optional: true, + Required: true, }, "location": { Type: schema.TypeList, @@ -62,9 +60,9 @@ func DataSourceDevice() *schema.Resource { }, "site_id": { Type: schema.TypeString, - Optional: true, + Computed: true, }, - "tags": tagsSchemaComputed(), + "tags": tftags.TagsSchemaComputed(), "type": { Type: schema.TypeString, Computed: true, @@ -77,77 +75,38 @@ func DataSourceDevice() *schema.Resource { } } -func DataSourceDeviceRead(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn - ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig - - input := &networkmanager.GetDevicesInput{ - GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), - } - - if v, ok := d.GetOk("id"); ok { - input.DeviceIds = aws.StringSlice([]string{v.(string)}) - } - - if v, ok := d.GetOk("site_id"); ok { - input.SiteId = aws.String(v.(string)) - } +func dataSourceDeviceRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig - log.Printf("[DEBUG] Reading Network Manager Device: %s", input) - output, err := conn.GetDevices(input) + globalNetworkID := d.Get("global_network_id").(string) + deviceID := d.Get("device_id").(string) + device, err := FindDeviceByTwoPartKey(ctx, conn, globalNetworkID, deviceID) if err != nil { - return fmt.Errorf("error reading Network Manager Device: %s", err) + return diag.Errorf("error reading Network Manager Device (%s): %s", deviceID, err) } - // do filtering here - var filteredDevices []*networkmanager.Device - if tags, ok := d.GetOk("tags"); ok { - keyValueTags := keyvaluetags.New(tags.(map[string]interface{})).IgnoreAws() - for _, device := range output.Devices { - tagsMatch := true - if len(keyValueTags) > 0 { - listTags := keyvaluetags.NetworkmanagerKeyValueTags(device.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) - tagsMatch = listTags.ContainsAll(keyValueTags) - } - if tagsMatch { - filteredDevices = append(filteredDevices, device) - } + d.SetId(deviceID) + d.Set("arn", device.DeviceArn) + d.Set("description", device.Description) + d.Set("device_id", device.DeviceId) + if device.Location != nil { + if err := d.Set("location", []interface{}{flattenLocation(device.Location)}); err != nil { + return diag.Errorf("error setting location: %s", err) } } else { - filteredDevices = output.Devices + d.Set("location", nil) } - - if output == nil || len(filteredDevices) == 0 { - return errors.New("error reading Network Manager Device: no results found") - } - - if len(filteredDevices) > 1 { - return errors.New("error reading Network Manager Device: more than one result found. Please try a more specific search criteria.") - } - - device := filteredDevices[0] - - if device == nil { - return errors.New("error reading Network Manager Device: empty result") - } - - d.Set("arn", device.DeviceArn) - d.Set("description", device.Description) d.Set("model", device.Model) d.Set("serial_number", device.SerialNumber) d.Set("site_id", device.SiteId) d.Set("type", device.Type) d.Set("vendor", device.Vendor) - if err := d.Set("location", flattenNetworkManagerLocation(device.Location)); err != nil { - return fmt.Errorf("error setting location: %s", err) - } - if err := d.Set("tags", keyvaluetags.NetworkmanagerKeyValueTags(device.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %s", err) + if err := d.Set("tags", KeyValueTags(device.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return diag.Errorf("error setting tags: %s", err) } - d.SetId(aws.StringValue(device.DeviceId)) - return nil } diff --git a/website/docs/d/networkmanager_device.html.markdown b/website/docs/d/networkmanager_device.html.markdown index 1d2b3d39a0c..41f31ee0cad 100644 --- a/website/docs/d/networkmanager_device.html.markdown +++ b/website/docs/d/networkmanager_device.html.markdown @@ -1,5 +1,5 @@ --- -subcategory: "Transit Gateway Network Manager" +subcategory: "Network Manager" layout: "aws" page_title: "AWS: aws_networkmanager_device" description: |- @@ -14,21 +14,16 @@ Retrieve information about a device. ```hcl data "aws_networkmanager_device" "example" { - id = var.global_network_id + global_network_id_id = var.global_network_id + device_id = var.device_id } ``` ## Argument Reference -* `id` - (Optional) The id of the specific device to retrieve. - +* `device_id` - (Required) The id of the specific device to retrieve. * `global_network_id` - (Required) The ID of the Global Network of the device to retrieve. -* `site_id` - (Optional) The ID of the Site of the device to retrieve. - -* `tags` - (Optional) A map of tags, each pair of which must exactly match - a pair on the desired device. - ## Attributes Reference In addition to all arguments above, the following attributes are exported: @@ -38,6 +33,8 @@ In addition to all arguments above, the following attributes are exported: * `type` - The type of device. * `model` - The model of device. * `serial_number` - The serial number of the device. +* `site_id` - The site of the device. +* `tags` - Key-value tags for the device. * `vendor` - The vendor of the device. The `location` object supports the following: From fc773ffffd356b7e6e4b7586050292d96ddacfbd Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 08:06:17 -0500 Subject: [PATCH 080/229] Start work on Device data source acceptance tests. --- .../networkmanager/{ignore => }/device_data_source_test.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename internal/service/networkmanager/{ignore => }/device_data_source_test.go (100%) diff --git a/internal/service/networkmanager/ignore/device_data_source_test.go b/internal/service/networkmanager/device_data_source_test.go similarity index 100% rename from internal/service/networkmanager/ignore/device_data_source_test.go rename to internal/service/networkmanager/device_data_source_test.go From 9dd6442d945635668697c006c4bd03961a3b4142 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 08:16:28 -0500 Subject: [PATCH 081/229] d/aws_networkmanager_device: Acceptance test. Acceptance test output: % TF_ACC=1 go test ./internal/service/networkmanager -v -count 1 -parallel 20 -run='TestAccNetworkManagerDeviceDataSource_' -timeout 180m === RUN TestAccNetworkManagerDeviceDataSource_basic === PAUSE TestAccNetworkManagerDeviceDataSource_basic === CONT TestAccNetworkManagerDeviceDataSource_basic --- PASS: TestAccNetworkManagerDeviceDataSource_basic (21.38s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 25.073s --- .../networkmanager/device_data_source_test.go | 94 ++++++------------- 1 file changed, 30 insertions(+), 64 deletions(-) diff --git a/internal/service/networkmanager/device_data_source_test.go b/internal/service/networkmanager/device_data_source_test.go index 0ec9c44544d..b621d20a537 100644 --- a/internal/service/networkmanager/device_data_source_test.go +++ b/internal/service/networkmanager/device_data_source_test.go @@ -4,106 +4,72 @@ import ( "fmt" "testing" + "github.com/aws/aws-sdk-go/service/networkmanager" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-provider-aws/internal/acctest" ) -func TestAccDataSourceDevice_basic(t *testing.T) { +func TestAccNetworkManagerDeviceDataSource_basic(t *testing.T) { dataSourceName := "data.aws_networkmanager_device.test" - dataSourceByIdName := "data.aws_networkmanager_device.test_by_id" - dataSourceBySiteIdName := "data.aws_networkmanager_device.test_by_site_id" - dataSourceByTagsName := "data.aws_networkmanager_device.test_by_tags" resourceName := "aws_networkmanager_device.test" - resourceSiteName := "aws_networkmanager_site.test" - resourceGlobalNetworkName := "aws_networkmanager_global_network.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - acctest.PreCheck(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAwsDeviceDestroy, + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, Steps: []resource.TestStep{ { - Config: testAccDataSourceDeviceConfig(), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrPair(dataSourceName, "id", resourceName, "id"), + Config: testAccDeviceDataSourceConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"), resource.TestCheckResourceAttrPair(dataSourceName, "description", resourceName, "description"), - resource.TestCheckResourceAttrPair(dataSourceName, "global_network_id", resourceGlobalNetworkName, "id"), + resource.TestCheckResourceAttrPair(dataSourceName, "device_id", resourceName, "id"), + resource.TestCheckResourceAttrPair(dataSourceName, "global_network_id", resourceName, "global_network_id"), + resource.TestCheckResourceAttrPair(dataSourceName, "location.#", resourceName, "location.#"), resource.TestCheckResourceAttrPair(dataSourceName, "model", resourceName, "model"), - resource.TestCheckResourceAttrPair(dataSourceName, "serial_number", resourceName, "serial_number"), - resource.TestCheckResourceAttrPair(dataSourceName, "site_id", resourceSiteName, "id"), + resource.TestCheckResourceAttrPair(dataSourceName, "site_id", resourceName, "site_id"), + resource.TestCheckResourceAttrPair(dataSourceName, "tags.%", resourceName, "tags.%"), resource.TestCheckResourceAttrPair(dataSourceName, "type", resourceName, "type"), resource.TestCheckResourceAttrPair(dataSourceName, "vendor", resourceName, "vendor"), - resource.TestCheckResourceAttrPair(dataSourceName, "tags.Name", resourceName, "tags.Name"), - resource.TestCheckResourceAttrPair(dataSourceName, "tags.OtherTag", resourceName, "tags.OtherTag"), - resource.TestCheckResourceAttr(dataSourceName, "location.#", "1"), - resource.TestCheckResourceAttr(dataSourceName, "location.0.address", ""), - resource.TestCheckResourceAttr(dataSourceName, "location.0.latitude", "18.0029784"), - resource.TestCheckResourceAttr(dataSourceName, "location.0.longitude", "-76.7897987"), - resource.TestCheckResourceAttrPair(dataSourceByIdName, "id", resourceName, "id"), - resource.TestCheckResourceAttrPair(dataSourceBySiteIdName, "site_id", resourceSiteName, "id"), - resource.TestCheckResourceAttrPair(dataSourceByTagsName, "tags.Name", resourceName, "tags.Name"), ), }, }, }) } -func testAccDataSourceDeviceConfig() string { +func testAccDeviceDataSourceConfig(rName string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { - description = "test" -} - -resource "aws_networkmanager_site" "test" { - description = "test" - global_network_id = aws_networkmanager_global_network.test.id - + tags = { + Name = %[1]q + } } resource "aws_networkmanager_device" "test" { - description = "test" - global_network_id = aws_networkmanager_global_network.test.id - site_id = aws_networkmanager_site.test.id - model = "abc" - serial_number = "123" - type = "office device" - vendor = "company" + global_network_id = aws_networkmanager_global_network.test.id + + description = "description1" + model = "model1" + serial_number = "sn1" + type = "type1" + vendor = "vendor1" location { - latitude = "18.0029784" - longitude = "-76.7897987" + address = "Address 1" + latitude = "1.1" + longitude = "-1.1" } tags = { - Name = "terraform-testacc-site-%d" - OtherTag = "some-value" + Name = %[1]q } } data "aws_networkmanager_device" "test" { - global_network_id = aws_networkmanager_device.test.global_network_id -} - -data "aws_networkmanager_device" "test_by_id" { global_network_id = aws_networkmanager_global_network.test.id - id = aws_networkmanager_device.test.id -} - -data "aws_networkmanager_device" "test_by_site_id" { - global_network_id = aws_networkmanager_device.test.global_network_id - site_id = aws_networkmanager_site.test.id -} - -data "aws_networkmanager_device" "test_by_tags" { - global_network_id = aws_networkmanager_global_network.test.id - - tags = { - Name = aws_networkmanager_device.test.tags["Name"] - } + device_id = aws_networkmanager_device.test.id } -`, sdkacctest.RandInt()) +`, rName) } From 25fec51d5c79de10bdcd991f6b33205c22e19d13 Mon Sep 17 00:00:00 2001 From: Mathijs van Mourick Date: Fri, 4 Mar 2022 14:17:05 +0100 Subject: [PATCH 082/229] Remove `ForceNew` behavior from `repository` attribute --- internal/service/amplify/app.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/service/amplify/app.go b/internal/service/amplify/app.go index f869b302e63..ea6be42f0f9 100644 --- a/internal/service/amplify/app.go +++ b/internal/service/amplify/app.go @@ -306,7 +306,6 @@ func ResourceApp() *schema.Resource { "repository": { Type: schema.TypeString, Optional: true, - ForceNew: true, ValidateFunc: validation.StringLenBetween(1, 1000), }, From 538b3ecd1a80c9325f60c48ac1d4ce38e38bddfe Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 08:25:59 -0500 Subject: [PATCH 083/229] d/aws_networkmanager_devices: New data source. Acceptance test output: % TF_ACC=1 go test ./internal/service/networkmanager -v -count 1 -parallel 20 -run='TestAccNetworkManagerDevicesDataSource_' -timeout 180m === RUN TestAccNetworkManagerDevicesDataSource_basic === PAUSE TestAccNetworkManagerDevicesDataSource_basic === CONT TestAccNetworkManagerDevicesDataSource_basic --- PASS: TestAccNetworkManagerDevicesDataSource_basic (22.37s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 25.960s --- .changelog/13251.txt | 8 +++ internal/provider/provider.go | 1 + .../networkmanager/devices_data_source.go | 62 ++++++++++++++++ .../devices_data_source_test.go | 70 +++++++++++++++++++ .../d/networkmanager_devices.html.markdown | 34 +++++++++ 5 files changed, 175 insertions(+) create mode 100644 internal/service/networkmanager/devices_data_source.go create mode 100644 internal/service/networkmanager/devices_data_source_test.go create mode 100644 website/docs/d/networkmanager_devices.html.markdown diff --git a/.changelog/13251.txt b/.changelog/13251.txt index 6c087cb2f61..9253ec4d8af 100644 --- a/.changelog/13251.txt +++ b/.changelog/13251.txt @@ -24,4 +24,12 @@ aws_networkmanager_site ```release-note:new-data-source aws_networkmanager_sites +``` + +```release-note:new-data-source +aws_networkmanager_device +``` + +```release-note:new-data-source +aws_networkmanager_devices ``` \ No newline at end of file diff --git a/internal/provider/provider.go b/internal/provider/provider.go index d36790f6684..2a400a9d526 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -714,6 +714,7 @@ func Provider() *schema.Provider { "aws_neptune_orderable_db_instance": neptune.DataSourceOrderableDBInstance(), "aws_networkmanager_device": networkmanager.DataSourceDevice(), + "aws_networkmanager_devices": networkmanager.DataSourceDevices(), "aws_networkmanager_global_network": networkmanager.DataSourceGlobalNetwork(), "aws_networkmanager_global_networks": networkmanager.DataSourceGlobalNetworks(), "aws_networkmanager_site": networkmanager.DataSourceSite(), diff --git a/internal/service/networkmanager/devices_data_source.go b/internal/service/networkmanager/devices_data_source.go new file mode 100644 index 00000000000..5571da3386b --- /dev/null +++ b/internal/service/networkmanager/devices_data_source.go @@ -0,0 +1,62 @@ +package networkmanager + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" +) + +func DataSourceDevices() *schema.Resource { + return &schema.Resource{ + ReadWithoutTimeout: dataSourceDevicesRead, + + Schema: map[string]*schema.Schema{ + "global_network_id": { + Type: schema.TypeString, + Required: true, + }, + "ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "tags": tftags.TagsSchema(), + }, + } +} + +func dataSourceDevicesRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig + tagsToMatch := tftags.New(d.Get("tags").(map[string]interface{})).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) + + output, err := FindDevices(ctx, conn, &networkmanager.GetDevicesInput{ + GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), + }) + + if err != nil { + return diag.Errorf("error listing Network Manager Devices: %s", err) + } + + var deviceIDs []string + + for _, v := range output { + if len(tagsToMatch) > 0 { + if !KeyValueTags(v.Tags).ContainsAll(tagsToMatch) { + continue + } + } + + deviceIDs = append(deviceIDs, aws.StringValue(v.DeviceId)) + } + + d.SetId(meta.(*conns.AWSClient).Region) + d.Set("ids", deviceIDs) + + return nil +} diff --git a/internal/service/networkmanager/devices_data_source_test.go b/internal/service/networkmanager/devices_data_source_test.go new file mode 100644 index 00000000000..7c6b0a0bdbf --- /dev/null +++ b/internal/service/networkmanager/devices_data_source_test.go @@ -0,0 +1,70 @@ +package networkmanager_test + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/networkmanager" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" +) + +func TestAccNetworkManagerDevicesDataSource_basic(t *testing.T) { + dataSourceAllName := "data.aws_networkmanager_devices.all" + dataSourceByTagsName := "data.aws_networkmanager_devices.by_tags" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccDevicesDataSourceConfig(rName), + Check: resource.ComposeTestCheckFunc( + acctest.CheckResourceAttrGreaterThanValue(dataSourceAllName, "ids.#", "1"), + resource.TestCheckResourceAttr(dataSourceByTagsName, "ids.#", "1"), + ), + }, + }, + }) +} + +func testAccDevicesDataSourceConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_device" "test1" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_device" "test2" { + global_network_id = aws_networkmanager_global_network.test.id +} + +data "aws_networkmanager_devices" "all" { + global_network_id = aws_networkmanager_global_network.test.id + + depends_on = [aws_networkmanager_device.test1, aws_networkmanager_device.test2] +} + +data "aws_networkmanager_devices" "by_tags" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } + + depends_on = [aws_networkmanager_device.test1, aws_networkmanager_device.test2] +} +`, rName) +} diff --git a/website/docs/d/networkmanager_devices.html.markdown b/website/docs/d/networkmanager_devices.html.markdown new file mode 100644 index 00000000000..d549a91da63 --- /dev/null +++ b/website/docs/d/networkmanager_devices.html.markdown @@ -0,0 +1,34 @@ +--- +subcategory: "Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_devices" +description: |- + Retrieve information about devices. +--- + +# Data Source: aws_networkmanager_devices + +Retrieve information about devices. + +## Example Usage + +```hcl +data "aws_networkmanager_devices" "example" { + global_network_id = var.global_network_id + + tags = { + Env = "test" + } +} +``` + +## Argument Reference + +* `global_network_id` - (Required) The ID of the Global Network of the devices to retrieve. +* `tags` - (Optional) Restricts the list to the devices with these tags. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `ids` - The IDs of the devices. From 19aa38cb668a8ca682f6d0226f206fb9b089fd15 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 08:27:26 -0500 Subject: [PATCH 084/229] Start work on Transit Gateway Registration resource. --- .../networkmanager/{ignore => }/transit_gateway_registration.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename internal/service/networkmanager/{ignore => }/transit_gateway_registration.go (100%) diff --git a/internal/service/networkmanager/ignore/transit_gateway_registration.go b/internal/service/networkmanager/transit_gateway_registration.go similarity index 100% rename from internal/service/networkmanager/ignore/transit_gateway_registration.go rename to internal/service/networkmanager/transit_gateway_registration.go From bfd685c4983e1ecc1a1a1245c1d367549edc4dcb Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 09:38:29 -0500 Subject: [PATCH 085/229] r/aws_networkmanager_transit_gateway_registration: Modernize resource. --- .changelog/13251.txt | 4 + .../transit_gateway_registration.go | 296 +++++++++++------- ...transit_gateway_registration.html.markdown | 6 +- 3 files changed, 185 insertions(+), 121 deletions(-) diff --git a/.changelog/13251.txt b/.changelog/13251.txt index 9253ec4d8af..8917cedbd05 100644 --- a/.changelog/13251.txt +++ b/.changelog/13251.txt @@ -10,6 +10,10 @@ aws_networkmanager_site aws_networkmanager_device ``` +```release-note:new-resource +aws_networkmanager_transit_gateway_registration +``` + ```release-note:new-data-source aws_networkmanager_global_network ``` diff --git a/internal/service/networkmanager/transit_gateway_registration.go b/internal/service/networkmanager/transit_gateway_registration.go index c831ba2dfb4..e1e92e6d99e 100644 --- a/internal/service/networkmanager/transit_gateway_registration.go +++ b/internal/service/networkmanager/transit_gateway_registration.go @@ -1,43 +1,36 @@ package networkmanager import ( + "context" + "errors" "fmt" "log" "strings" "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) func ResourceTransitGatewayRegistration() *schema.Resource { return &schema.Resource{ - Create: ResourceTransitGatewayRegistrationCreate, - Read: ResourceTransitGatewayRegistrationRead, - Delete: ResourceTransitGatewayRegistrationDelete, + CreateWithoutTimeout: resourceTransitGatewayRegistrationCreate, + ReadWithoutTimeout: resourceTransitGatewayRegistrationRead, + DeleteWithoutTimeout: resourceTransitGatewayRegistrationDelete, + Importer: &schema.ResourceImporter{ - State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - idErr := fmt.Errorf("Expected ID in format of arn:aws:ec2:REGION:ACCOUNTID:transit-gateway/TGWID,GLOBALNETWORKID and provided: %s", d.Id()) - - identifiers := strings.Split(d.Id(), ",") - if len(identifiers) != 2 { - return nil, idErr - } - if arn.IsARN(identifiers[0]) { - d.Set("transit_gateway_arn", identifiers[0]) - } else { - return nil, idErr - } - - d.Set("global_network_id", identifiers[1]) - - return []*schema.ResourceData{d}, nil - }, + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), }, Schema: map[string]*schema.Schema{ @@ -55,176 +48,243 @@ func ResourceTransitGatewayRegistration() *schema.Resource { } } -func ResourceTransitGatewayRegistrationCreate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn - - globalNetworkId := d.Get("global_network_id").(string) - transitGatewayArn := d.Get("transit_gateway_arn").(string) +func resourceTransitGatewayRegistrationCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + globalNetworkID := d.Get("global_network_id").(string) + transitGatewayARN := d.Get("transit_gateway_arn").(string) + id := TransitGatewayRegistrationCreateResourceID(globalNetworkID, transitGatewayARN) input := &networkmanager.RegisterTransitGatewayInput{ - GlobalNetworkId: aws.String(globalNetworkId), - TransitGatewayArn: aws.String(transitGatewayArn), + GlobalNetworkId: aws.String(globalNetworkID), + TransitGatewayArn: aws.String(transitGatewayARN), } - log.Printf("[DEBUG] Creating Network Manager Transit gateway Registration: %s", input) + log.Printf("[DEBUG] Creating Network Manager Transit Gateway Registration: %s", input) + _, err := conn.RegisterTransitGatewayWithContext(ctx, input) - output, err := conn.RegisterTransitGateway(input) if err != nil { - return fmt.Errorf("error creating Network Manager Transit Gateway Registration: %s", err) + return diag.Errorf("error creating Network Manager Transit Gateway Registration (%s): %s", id, err) } - d.SetId(fmt.Sprintf("%s,%s", transitGatewayArn, globalNetworkId)) - - stateConf := &resource.StateChangeConf{ - Pending: []string{networkmanager.TransitGatewayRegistrationStatePending}, - Target: []string{networkmanager.TransitGatewayRegistrationStateAvailable}, - Refresh: networkmanagerTransitGatewayRegistrationRefreshFunc(conn, aws.StringValue(output.TransitGatewayRegistration.GlobalNetworkId), aws.StringValue(output.TransitGatewayRegistration.TransitGatewayArn)), - Timeout: 10 * time.Minute, - } + d.SetId(id) - _, err = stateConf.WaitForState() - if err != nil { - return fmt.Errorf("error waiting for Network Manager Transit Gateway Registration (%s) availability: %s", d.Id(), err) + if _, err := waitTransitGatewayRegistrationCreated(ctx, conn, globalNetworkID, transitGatewayARN, d.Timeout(schema.TimeoutCreate)); err != nil { + return diag.Errorf("error waiting for Network Manager Transit Gateway Attachment (%s) create: %s", d.Id(), err) } - return ResourceTransitGatewayRegistrationRead(d, meta) + return resourceTransitGatewayRegistrationRead(ctx, d, meta) } -func ResourceTransitGatewayRegistrationRead(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn - - transitGatewayRegistration, err := networkmanagerDescribeTransitGatewayRegistration(conn, d.Get("global_network_id").(string), d.Get("transit_gateway_arn").(string)) +func resourceTransitGatewayRegistrationRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn - if tfawserr.ErrCodeEquals(err, "InvalidTransitGatewayRegistrationID.NotFound", "") { - log.Printf("[WARN] Network Manager Transit Gateway Registration (%s) not found, removing from state", d.Id()) - d.SetId("") - return nil - } + globalNetworkID, transitGatewayARN, err := TransitGatewayRegistrationParseResourceID(d.Id()) if err != nil { - return fmt.Errorf("error reading Network Manager Transit Gateway Registration: %s", err) + return diag.FromErr(err) } - if transitGatewayRegistration == nil { - log.Printf("[WARN] Network Manager Transit Gateway Registration (%s) not found, removing from state", d.Id()) + transitGatewayRegistration, err := FindTransitGatewayRegistrationByTwoPartKey(ctx, conn, globalNetworkID, transitGatewayARN) + + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Network Manager Transit Gateway Registration %s not found, removing from state", d.Id()) d.SetId("") return nil } - if aws.StringValue(transitGatewayRegistration.State.Code) == networkmanager.TransitGatewayRegistrationStateDeleting || aws.StringValue(transitGatewayRegistration.State.Code) == networkmanager.TransitGatewayRegistrationStateDeleted { - log.Printf("[WARN] Network Manager Transit Gateway Registration (%s) in deleted state (%s,%s), removing from state", d.Id(), aws.StringValue(transitGatewayRegistration.State.Code), aws.StringValue(transitGatewayRegistration.State.Message)) - d.SetId("") - return nil + if err != nil { + return diag.Errorf("error reading Network Manager Transit Gateway Registration (%s): %s", d.Id(), err) } + d.Set("global_network_id", transitGatewayRegistration.GlobalNetworkId) + d.Set("transit_gateway_arn", transitGatewayRegistration.TransitGatewayArn) + return nil } -func ResourceTransitGatewayRegistrationDelete(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).networkmanagerconn +func resourceTransitGatewayRegistrationDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn - input := &networkmanager.DeregisterTransitGatewayInput{ - GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), - TransitGatewayArn: aws.String(d.Get("transit_gateway_arn").(string)), + globalNetworkID, transitGatewayARN, err := TransitGatewayRegistrationParseResourceID(d.Id()) + + if err != nil { + return diag.FromErr(err) } - log.Printf("[DEBUG] Deleting Network Manager Transit Gateway Registration (%s): %s", d.Id(), input) - req, _ := conn.DeregisterTransitGatewayRequest(input) - err := req.Send() + log.Printf("[DEBUG] Deleting Network Manager Transit Gateway Registration: %s", d.Id()) + _, err = conn.DeregisterTransitGatewayWithContext(ctx, &networkmanager.DeregisterTransitGatewayInput{ + GlobalNetworkId: aws.String(globalNetworkID), + TransitGatewayArn: aws.String(transitGatewayARN), + }) - if tfawserr.ErrCodeEquals(err, "InvalidTransitGatewayRegistrationArn.NotFound", "") { + if globalNetworkIDNotFoundError(err) || tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeResourceNotFoundException) { return nil } if err != nil { - return fmt.Errorf("error deleting Network Manager Transit Gateway Registration: %s", err) + return diag.Errorf("error deleting Network Manager Transit Gateway Registration (%s): %s", d.Id(), err) } - if err := waitForTransitGatewayRegistrationDeletion(conn, d.Get("global_network_id").(string), d.Get("transit_gateway_arn").(string)); err != nil { - return fmt.Errorf("error waiting for Network Manager Transit Gateway Registration (%s) deletion: %s", d.Id(), err) + if _, err := waitTransitGatewayRegistrationDeleted(ctx, conn, globalNetworkID, transitGatewayARN, d.Timeout(schema.TimeoutDelete)); err != nil { + return diag.Errorf("error waiting for Network Manager Transit Gateway Registration (%s) delete: %s", d.Id(), err) } return nil } -func networkmanagerTransitGatewayRegistrationRefreshFunc(conn *networkmanager.NetworkManager, globalNetworkID, transitGatewayArn string) resource.StateRefreshFunc { - return func() (interface{}, string, error) { - transitGatewayRegistration, err := networkmanagerDescribeTransitGatewayRegistration(conn, globalNetworkID, transitGatewayArn) +func FindTransitGatewayRegistration(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.GetTransitGatewayRegistrationsInput) (*networkmanager.TransitGatewayRegistration, error) { + output, err := FindTransitGatewayRegistrations(ctx, conn, input) + + if err != nil { + return nil, err + } + + if len(output) == 0 || output[0] == nil || output[0].State == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } - if tfawserr.ErrCodeEquals(err, "InvalidTransitGatewayRegistrationID.NotFound", "") { - return nil, "DELETED", nil + return output[0], nil +} + +func FindTransitGatewayRegistrations(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.GetTransitGatewayRegistrationsInput) ([]*networkmanager.TransitGatewayRegistration, error) { + var output []*networkmanager.TransitGatewayRegistration + + err := conn.GetTransitGatewayRegistrationsPagesWithContext(ctx, input, func(page *networkmanager.GetTransitGatewayRegistrationsOutput, lastPage bool) bool { + if page == nil { + return !lastPage } - if err != nil { - return nil, "", fmt.Errorf("error reading Network Manager Transit Gateway Registration (%s,%s): %s", transitGatewayArn, globalNetworkID, err) + for _, v := range page.TransitGatewayRegistrations { + if v == nil { + continue + } + + output = append(output, v) } - if transitGatewayRegistration == nil { - return nil, "DELETED", nil + return !lastPage + }) + + if globalNetworkIDNotFoundError(err) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, } + } - return transitGatewayRegistration, aws.StringValue(transitGatewayRegistration.State.Code), nil + if err != nil { + return nil, err } + + return output, nil } -func networkmanagerDescribeTransitGatewayRegistration(conn *networkmanager.NetworkManager, globalNetworkID, transitGatewayArn string) (*networkmanager.TransitGatewayRegistration, error) { +func FindTransitGatewayRegistrationByTwoPartKey(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, transitGatewayARN string) (*networkmanager.TransitGatewayRegistration, error) { input := &networkmanager.GetTransitGatewayRegistrationsInput{ GlobalNetworkId: aws.String(globalNetworkID), - TransitGatewayArns: []*string{aws.String(transitGatewayArn)}, + TransitGatewayArns: aws.StringSlice([]string{transitGatewayARN}), } - log.Printf("[DEBUG] Reading Network Manager Transit Gateway Registration (%s): %s", transitGatewayArn, input) - for { - output, err := conn.GetTransitGatewayRegistrations(input) + output, err := FindTransitGatewayRegistration(ctx, conn, input) - if err != nil { - return nil, err + if err != nil { + return nil, err + } + + if state := aws.StringValue(output.State.Code); state == networkmanager.TransitGatewayRegistrationStateDeleted { + return nil, &resource.NotFoundError{ + Message: state, + LastRequest: input, } + } - if output == nil || len(output.TransitGatewayRegistrations) == 0 { - return nil, nil + // Eventual consistency check. + if aws.StringValue(output.GlobalNetworkId) != globalNetworkID || aws.StringValue(output.TransitGatewayArn) != transitGatewayARN { + return nil, &resource.NotFoundError{ + LastRequest: input, } + } - for _, transitGatewayRegistration := range output.TransitGatewayRegistrations { - if transitGatewayRegistration == nil { - continue - } + return output, nil +} - if aws.StringValue(transitGatewayRegistration.TransitGatewayArn) == transitGatewayArn { - return transitGatewayRegistration, nil - } +func statusTransitGatewayRegistrationState(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, transitGatewayARN string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + output, err := FindTransitGatewayRegistrationByTwoPartKey(ctx, conn, globalNetworkID, transitGatewayARN) + + if tfresource.NotFound(err) { + return nil, "", nil } - if aws.StringValue(output.NextToken) == "" { - break + if err != nil { + return nil, "", err } - input.NextToken = output.NextToken + return output, aws.StringValue(output.State.Code), nil + } +} + +func waitTransitGatewayRegistrationCreated(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, transitGatewayARN string, timeout time.Duration) (*networkmanager.TransitGatewayRegistration, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.TransitGatewayRegistrationStatePending}, + Target: []string{networkmanager.TransitGatewayRegistrationStateAvailable}, + Timeout: timeout, + Refresh: statusTransitGatewayRegistrationState(ctx, conn, globalNetworkID, transitGatewayARN), } - return nil, nil + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*networkmanager.TransitGatewayRegistration); ok { + if state := aws.StringValue(output.State.Code); state == networkmanager.TransitGatewayRegistrationStateFailed { + tfresource.SetLastError(err, errors.New(aws.StringValue(output.State.Message))) + } + + return output, err + } + + return nil, err } -func waitForTransitGatewayRegistrationDeletion(conn *networkmanager.NetworkManager, globalNetworkID, transitGatewayArn string) error { +func waitTransitGatewayRegistrationDeleted(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, transitGatewayARN string, timeout time.Duration) (*networkmanager.TransitGatewayRegistration, error) { stateConf := &resource.StateChangeConf{ - Pending: []string{ - networkmanager.TransitGatewayRegistrationStateAvailable, - networkmanager.TransitGatewayRegistrationStateDeleting, - }, - Target: []string{ - networkmanager.TransitGatewayRegistrationStateDeleted, - }, - Refresh: networkmanagerTransitGatewayRegistrationRefreshFunc(conn, globalNetworkID, transitGatewayArn), - Timeout: 10 * time.Minute, - NotFoundChecks: 1, + Pending: []string{networkmanager.TransitGatewayRegistrationStateAvailable, networkmanager.TransitGatewayRegistrationStateDeleting}, + Target: []string{}, + Timeout: timeout, + Refresh: statusTransitGatewayRegistrationState(ctx, conn, globalNetworkID, transitGatewayARN), } - log.Printf("[DEBUG] Waiting for Network Manager Transit Gateway Registration (%s) deletion", transitGatewayArn) - _, err := stateConf.WaitForState() + outputRaw, err := stateConf.WaitForStateContext(ctx) - if tfresource.NotFound(err) { - return nil + if output, ok := outputRaw.(*networkmanager.TransitGatewayRegistration); ok { + if state := aws.StringValue(output.State.Code); state == networkmanager.TransitGatewayRegistrationStateFailed { + tfresource.SetLastError(err, errors.New(aws.StringValue(output.State.Message))) + } + + return output, err + } + + return nil, err +} + +const transitGatewayRegistrationIDSeparator = "," + +func TransitGatewayRegistrationCreateResourceID(globalNetworkID, transitGatewayARN string) string { + parts := []string{globalNetworkID, transitGatewayARN} + id := strings.Join(parts, transitGatewayRegistrationIDSeparator) + + return id +} + +func TransitGatewayRegistrationParseResourceID(id string) (string, string, error) { + parts := strings.Split(id, transitGatewayRegistrationIDSeparator) + + if len(parts) == 2 && parts[0] != "" && parts[1] != "" { + return parts[0], parts[1], nil } - return err + return "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected GLOBAL-NETWORK-ID%[2]sTRANSIT-GATEWAY-ARN", id, transitGatewayRegistrationIDSeparator) } diff --git a/website/docs/r/networkmanager_transit_gateway_registration.html.markdown b/website/docs/r/networkmanager_transit_gateway_registration.html.markdown index f48c8fd5a04..596883e4508 100644 --- a/website/docs/r/networkmanager_transit_gateway_registration.html.markdown +++ b/website/docs/r/networkmanager_transit_gateway_registration.html.markdown @@ -1,5 +1,5 @@ --- -subcategory: "Transit Gateway Network Manager" +subcategory: "Network Manager" layout: "aws" page_title: "AWS: aws_networkmanager_transit_gateway_registration" description: |- @@ -36,8 +36,8 @@ The following arguments are supported: ## Import -`aws_networkmanager_transit_gateway_registration` can be imported using the transit gateway ARN and the global network ID, e.g. +`aws_networkmanager_transit_gateway_registration` can be imported using the global network ID and transit gateway ARN, e.g. ``` -$ terraform import aws_networkmanager_transit_gateway_registration.example arn:aws:ec2:us-west-2:123456789012:transit-gateway/tgw-123abc05e04123abc,global-network-0d47f6t230mz46dy4 +$ terraform import aws_networkmanager_transit_gateway_registration.example global-network-0d47f6t230mz46dy4,arn:aws:ec2:us-west-2:123456789012:transit-gateway/tgw-123abc05e04123abc ``` From de390ee2e9588b32b4520be42e1fcb5f9fc7817f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 10:55:27 -0500 Subject: [PATCH 086/229] Start work on Transit Gateway Registration acceptance tests. --- internal/provider/provider.go | 7 ++++--- .../{ignore => }/transit_gateway_registration_test.go | 0 2 files changed, 4 insertions(+), 3 deletions(-) rename internal/service/networkmanager/{ignore => }/transit_gateway_registration_test.go (100%) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 2a400a9d526..9e9a6aa58ab 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1584,9 +1584,10 @@ func Provider() *schema.Provider { "aws_networkfirewall_resource_policy": networkfirewall.ResourceResourcePolicy(), "aws_networkfirewall_rule_group": networkfirewall.ResourceRuleGroup(), - "aws_networkmanager_device": networkmanager.ResourceDevice(), - "aws_networkmanager_global_network": networkmanager.ResourceGlobalNetwork(), - "aws_networkmanager_site": networkmanager.ResourceSite(), + "aws_networkmanager_device": networkmanager.ResourceDevice(), + "aws_networkmanager_global_network": networkmanager.ResourceGlobalNetwork(), + "aws_networkmanager_site": networkmanager.ResourceSite(), + "aws_networkmanager_transit_gateway_registration": networkmanager.ResourceTransitGatewayRegistration(), "aws_opsworks_application": opsworks.ResourceApplication(), "aws_opsworks_custom_layer": opsworks.ResourceCustomLayer(), diff --git a/internal/service/networkmanager/ignore/transit_gateway_registration_test.go b/internal/service/networkmanager/transit_gateway_registration_test.go similarity index 100% rename from internal/service/networkmanager/ignore/transit_gateway_registration_test.go rename to internal/service/networkmanager/transit_gateway_registration_test.go From ba8ae8c3a0236b0fa75df61ca24da62974ffd00f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 11:34:54 -0500 Subject: [PATCH 087/229] r/aws_networkmanager_transit_gateway_registration: Acceptance tests. Acceptance test output: % TF_ACC=1 go test ./internal/service/networkmanager -v -count 1 -parallel 20 -run='TestAccNetworkManageTransitGatewayRegistration_' -timeout 180m === RUN TestAccNetworkManageTransitGatewayRegistration_basic === PAUSE TestAccNetworkManageTransitGatewayRegistration_basic === RUN TestAccNetworkManageTransitGatewayRegistration_disappears === PAUSE TestAccNetworkManageTransitGatewayRegistration_disappears === RUN TestAccNetworkManageTransitGatewayRegistration_disappears_TransitGateway === PAUSE TestAccNetworkManageTransitGatewayRegistration_disappears_TransitGateway === CONT TestAccNetworkManageTransitGatewayRegistration_basic === CONT TestAccNetworkManageTransitGatewayRegistration_disappears_TransitGateway === CONT TestAccNetworkManageTransitGatewayRegistration_disappears --- PASS: TestAccNetworkManageTransitGatewayRegistration_basic (257.06s) --- PASS: TestAccNetworkManageTransitGatewayRegistration_disappears (259.61s) --- PASS: TestAccNetworkManageTransitGatewayRegistration_disappears_TransitGateway (343.08s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 346.901s --- .../transit_gateway_registration_test.go | 230 ++++++++---------- 1 file changed, 108 insertions(+), 122 deletions(-) diff --git a/internal/service/networkmanager/transit_gateway_registration_test.go b/internal/service/networkmanager/transit_gateway_registration_test.go index 3bc0637e8f7..5d66a7cb910 100644 --- a/internal/service/networkmanager/transit_gateway_registration_test.go +++ b/internal/service/networkmanager/transit_gateway_registration_test.go @@ -1,180 +1,166 @@ -package networkmanager +package networkmanager_test import ( + "context" "fmt" - "log" "testing" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/networkmanager" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" - "github.com/hashicorp/go-multierror" + 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" "github.com/hashicorp/terraform-provider-aws/internal/acctest" - "github.com/hashicorp/terraform-provider-aws/internal/ec2" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tfec2 "github.com/hashicorp/terraform-provider-aws/internal/service/ec2" + tfnetworkmanager "github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -func init() { - resource.AddTestSweepers("aws_networkmanager_transit_gateway_registration", &resource.Sweeper{ - Name: "aws_networkmanager_transit_gateway_registration", - F: testSweepTransitGatewayRegistration, - }) -} -func testSweepTransitGatewayRegistration(region string) error { - client, err := sharedClientForRegion(region) - if err != nil { - return fmt.Errorf("error getting client: %s", err) - } - conn := client.(*AWSClient).networkmanagerconn - var sweeperErrs *multierror.Error - err = conn.GetTransitGatewayRegistrationsPages(&networkmanager.GetTransitGatewayRegistrationsInput{}, - func(page *networkmanager.GetTransitGatewayRegistrationsOutput, lastPage bool) bool { - for _, transitGatewayRegistration := range page.TransitGatewayRegistrations { - input := &networkmanager.DeregisterTransitGatewayInput{ - GlobalNetworkId: transitGatewayRegistration.GlobalNetworkId, - TransitGatewayArn: transitGatewayRegistration.TransitGatewayArn, - } - transitGatewayArn := aws.StringValue(transitGatewayRegistration.TransitGatewayArn) - globalNetworkID := aws.StringValue(transitGatewayRegistration.GlobalNetworkId) - log.Printf("[INFO] Deleting Network Manager Transit Gateway Registration: %s", transitGatewayArn) - req, _ := conn.DeregisterTransitGatewayRequest(input) - err = req.Send() - if tfawserr.ErrCodeEquals(err, "InvalidTransitGatewayRegistrationArn.NotFound", "") { - continue - } - if err != nil { - sweeperErr := fmt.Errorf("failed to delete Network Manager Transit Gateway Registration %s: %s", transitGatewayArn, err) - log.Printf("[ERROR] %s", sweeperErr) - sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) - continue - } - if err := waitForTransitGatewayRegistrationDeletion(conn, globalNetworkID, transitGatewayArn); err != nil { - sweeperErr := fmt.Errorf("error waiting for Network Manager Transit Gateway Registration (%s) deletion: %s", transitGatewayArn, err) - log.Printf("[ERROR] %s", sweeperErr) - sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) - continue - } - } - return !lastPage - }) - if testSweepSkipSweepError(err) { - log.Printf("[WARN] Skipping Network Manager Transit Gateway Registration sweep for %s: %s", region, err) - return nil - } - if err != nil { - return fmt.Errorf("Error retrieving Network Manager Transit Gateway Registrations: %s", err) - } - return sweeperErrs.ErrorOrNil() -} -func TestAccTransitGatewayRegistration_basic(t *testing.T) { +func TestAccNetworkManageTransitGatewayRegistration_basic(t *testing.T) { resourceName := "aws_networkmanager_transit_gateway_registration.test" - gloablNetworkResourceName := "aws_networkmanager_global_network.test" - gloablNetwork2ResourceName := "aws_networkmanager_global_network.test2" - transitGatewayResourceName := "aws_ec2_transit_gateway.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); ec2.testAccPreCheckTransitGateway(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAwsTransitGatewayRegistrationDestroy, + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckTransitGatewayRegistrationDestroy, Steps: []resource.TestStep{ { - Config: testAccTransitGatewayRegistrationConfig(), + Config: testAccTransitGatewayRegistrationConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsTransitGatewayRegistrationExists(resourceName), - resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetworkResourceName, "id"), - resource.TestCheckResourceAttrPair(resourceName, "transit_gateway_arn", transitGatewayResourceName, "arn"), + testAccCheckTransitGatewayRegistrationExists(resourceName), ), }, { ResourceName: resourceName, ImportState: true, - ImportStateIdFunc: testAccTransitGatewayRegistrationImportStateIdFunc(resourceName), ImportStateVerify: true, }, + }, + }) +} + +func TestAccNetworkManageTransitGatewayRegistration_disappears(t *testing.T) { + resourceName := "aws_networkmanager_transit_gateway_registration.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckTransitGatewayRegistrationDestroy, + Steps: []resource.TestStep{ { - Config: testAccTransitGatewayRegistrationConfig_Update(), + Config: testAccTransitGatewayRegistrationConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAwsTransitGatewayRegistrationExists(resourceName), - resource.TestCheckResourceAttrPair(resourceName, "global_network_id", gloablNetwork2ResourceName, "id"), - resource.TestCheckResourceAttrPair(resourceName, "transit_gateway_arn", transitGatewayResourceName, "arn"), + testAccCheckTransitGatewayRegistrationExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfnetworkmanager.ResourceTransitGatewayRegistration(), resourceName), ), + ExpectNonEmptyPlan: true, }, }, }) } -func testAccCheckAwsTransitGatewayRegistrationDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn + +func TestAccNetworkManageTransitGatewayRegistration_disappears_TransitGateway(t *testing.T) { + resourceName := "aws_networkmanager_transit_gateway_registration.test" + transitGatewayResourceName := "aws_ec2_transit_gateway.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckTransitGatewayRegistrationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTransitGatewayRegistrationConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckTransitGatewayRegistrationExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfec2.ResourceTransitGateway(), transitGatewayResourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccCheckTransitGatewayRegistrationDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn + for _, rs := range s.RootModule().Resources { if rs.Type != "aws_networkmanager_transit_gateway_registration" { continue } - transitGatewayArn, err := networkmanagerDescribeTransitGatewayRegistration(conn, rs.Primary.Attributes["global_network_id"], rs.Primary.Attributes["transit_gateway_arn"]) + + globalNetworkID, transitGatewayARN, err := tfnetworkmanager.TransitGatewayRegistrationParseResourceID(rs.Primary.ID) + if err != nil { - if tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeValidationException, "") { - return nil - } return err } - if transitGatewayArn == nil { + + _, err = tfnetworkmanager.FindTransitGatewayRegistrationByTwoPartKey(context.TODO(), conn, globalNetworkID, transitGatewayARN) + + if tfresource.NotFound(err) { continue } - return fmt.Errorf("Expected Transit Gateway Registration to be destroyed, %s found", rs.Primary.ID) + + if err != nil { + return err + } + + return fmt.Errorf("Network Manager Transit Gateway Registration %s still exists", rs.Primary.ID) } + return nil } -func testAccCheckAwsTransitGatewayRegistrationExists(name string) resource.TestCheckFunc { + +func testAccCheckTransitGatewayRegistrationExists(n string) resource.TestCheckFunc { return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[name] + rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Not found: %s", name) + return fmt.Errorf("Not found: %s", n) } - conn := testAccProvider.Meta().(*AWSClient).networkmanagerconn - transitGatewayArn, err := networkmanagerDescribeTransitGatewayRegistration(conn, rs.Primary.Attributes["global_network_id"], rs.Primary.Attributes["transit_gateway_arn"]) + + if rs.Primary.ID == "" { + return fmt.Errorf("No Network Manager Transit Gateway Registration ID is set") + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn + + globalNetworkID, transitGatewayARN, err := tfnetworkmanager.TransitGatewayRegistrationParseResourceID(rs.Primary.ID) + if err != nil { return err } - if transitGatewayArn == nil { - return fmt.Errorf("Network Manager Transit Gateway Registration not found") - } - if aws.StringValue(transitGatewayArn.State.Code) != networkmanager.TransitGatewayRegistrationStateAvailable && aws.StringValue(transitGatewayArn.State.Code) != networkmanager.TransitGatewayRegistrationStatePending { - return fmt.Errorf("Network Manager Transit Gateway Registration (%s) exists in (%s) state", rs.Primary.Attributes["transit_gateway_arn"], aws.StringValue(transitGatewayArn.State.Code)) + + _, err = tfnetworkmanager.FindTransitGatewayRegistrationByTwoPartKey(context.TODO(), conn, globalNetworkID, transitGatewayARN) + + if err != nil { + return err } - return err + + return nil } } -func testAccTransitGatewayRegistrationConfig() string { - return ` +func testAccTransitGatewayRegistrationConfig(rName string) string { + return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { - description = "test" + tags = { + Name = %[1]q + } } -resource "aws_ec2_transit_gateway" "test" {} -resource "aws_networkmanager_transit_gateway_registration" "test" { - global_network_id = aws_networkmanager_global_network.test.id - transit_gateway_arn = aws_ec2_transit_gateway.test.arn -} -` -} -func testAccTransitGatewayRegistrationConfig_Update() string { - return ` -resource "aws_networkmanager_global_network" "test" { - description = "test" -} -resource "aws_networkmanager_global_network" "test2" { - description = "test2" + +resource "aws_ec2_transit_gateway" "test" { + tags = { + Name = %[1]q + } } -resource "aws_ec2_transit_gateway" "test" {} + resource "aws_networkmanager_transit_gateway_registration" "test" { - global_network_id = aws_networkmanager_global_network.test2.id + global_network_id = aws_networkmanager_global_network.test.id transit_gateway_arn = aws_ec2_transit_gateway.test.arn } -` -} -func testAccTransitGatewayRegistrationImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { - return func(s *terraform.State) (string, error) { - rs, ok := s.RootModule().Resources[resourceName] - if !ok { - return "", fmt.Errorf("Not found: %s", resourceName) - } - return fmt.Sprintf("%s,%s", rs.Primary.Attributes["transit_gateway_arn"], rs.Primary.Attributes["global_network_id"]), nil - } +`, rName) } From 05bd6710ed5bd79942f1048d0e0e3f80e5389b4a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 11:58:06 -0500 Subject: [PATCH 088/229] r/aws_networkmanager_global_network: Remove Transit Gateway associations on resource Delete. Acceptance test output: % make testacc TESTS=TestAccNetworkManageTransitGatewayRegistration_basic PKG=networkmanager ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/networkmanager/... -v -count 1 -parallel 20 -run='TestAccNetworkManageTransitGatewayRegistration_basic' -timeout 180m === RUN TestAccNetworkManageTransitGatewayRegistration_basic === PAUSE TestAccNetworkManageTransitGatewayRegistration_basic === CONT TestAccNetworkManageTransitGatewayRegistration_basic --- PASS: TestAccNetworkManageTransitGatewayRegistration_basic (280.23s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 283.980s --- .../service/networkmanager/global_network.go | 28 ++++++++++++++++++- .../transit_gateway_registration.go | 22 +++++++++++---- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/internal/service/networkmanager/global_network.go b/internal/service/networkmanager/global_network.go index 01586e29efc..59d43b2aade 100644 --- a/internal/service/networkmanager/global_network.go +++ b/internal/service/networkmanager/global_network.go @@ -153,8 +153,34 @@ func resourceGlobalNetworkUpdate(ctx context.Context, d *schema.ResourceData, me func resourceGlobalNetworkDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*conns.AWSClient).NetworkManagerConn + tgwRegistrations, err := FindTransitGatewayRegistrations(ctx, conn, &networkmanager.GetTransitGatewayRegistrationsInput{ + GlobalNetworkId: aws.String(d.Id()), + }) + + if tfresource.NotFound(err) { + err = nil + } + + if err != nil { + return diag.Errorf("error listing Transit Gateway Registrations (%s): %s", d.Id(), err) + } + + var diags diag.Diagnostics + + for _, v := range tgwRegistrations { + err := deregisterTransitGateway(ctx, conn, d.Id(), aws.StringValue(v.TransitGatewayArn), d.Timeout(schema.TimeoutDelete)) + + if err != nil { + diags = append(diags, diag.FromErr(err)...) + } + } + + if diags.HasError() { + return diags + } + log.Printf("[DEBUG] Deleting Network Manager Global Network: %s", d.Id()) - _, err := tfresource.RetryWhenContext(ctx, globalNetworkValidationExceptionTimeout, + _, err = tfresource.RetryWhenContext(ctx, globalNetworkValidationExceptionTimeout, func() (interface{}, error) { return conn.DeleteGlobalNetworkWithContext(ctx, &networkmanager.DeleteGlobalNetworkInput{ GlobalNetworkId: aws.String(d.Id()), diff --git a/internal/service/networkmanager/transit_gateway_registration.go b/internal/service/networkmanager/transit_gateway_registration.go index e1e92e6d99e..c3d9a9bc8cf 100644 --- a/internal/service/networkmanager/transit_gateway_registration.go +++ b/internal/service/networkmanager/transit_gateway_registration.go @@ -111,8 +111,20 @@ func resourceTransitGatewayRegistrationDelete(ctx context.Context, d *schema.Res return diag.FromErr(err) } - log.Printf("[DEBUG] Deleting Network Manager Transit Gateway Registration: %s", d.Id()) - _, err = conn.DeregisterTransitGatewayWithContext(ctx, &networkmanager.DeregisterTransitGatewayInput{ + err = deregisterTransitGateway(ctx, conn, globalNetworkID, transitGatewayARN, d.Timeout(schema.TimeoutDelete)) + + if err != nil { + return diag.FromErr(err) + } + + return nil +} + +func deregisterTransitGateway(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, transitGatewayARN string, timeout time.Duration) error { + id := TransitGatewayRegistrationCreateResourceID(globalNetworkID, transitGatewayARN) + + log.Printf("[DEBUG] Deleting Network Manager Transit Gateway Registration: %s", id) + _, err := conn.DeregisterTransitGatewayWithContext(ctx, &networkmanager.DeregisterTransitGatewayInput{ GlobalNetworkId: aws.String(globalNetworkID), TransitGatewayArn: aws.String(transitGatewayARN), }) @@ -122,11 +134,11 @@ func resourceTransitGatewayRegistrationDelete(ctx context.Context, d *schema.Res } if err != nil { - return diag.Errorf("error deleting Network Manager Transit Gateway Registration (%s): %s", d.Id(), err) + return fmt.Errorf("error deleting Network Manager Transit Gateway Registration (%s): %w", id, err) } - if _, err := waitTransitGatewayRegistrationDeleted(ctx, conn, globalNetworkID, transitGatewayARN, d.Timeout(schema.TimeoutDelete)); err != nil { - return diag.Errorf("error waiting for Network Manager Transit Gateway Registration (%s) delete: %s", d.Id(), err) + if _, err := waitTransitGatewayRegistrationDeleted(ctx, conn, globalNetworkID, transitGatewayARN, timeout); err != nil { + return fmt.Errorf("error waiting for Network Manager Transit Gateway Registration (%s) delete: %w", id, err) } return nil From 1745ee62e4cd2a50963d3a8e8da2fa138855c5fc Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 12:14:51 -0500 Subject: [PATCH 089/229] Serialize Transit Gateway Association tests. --- .../transit_gateway_registration_test.go | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/internal/service/networkmanager/transit_gateway_registration_test.go b/internal/service/networkmanager/transit_gateway_registration_test.go index 5d66a7cb910..7f0b2c0c859 100644 --- a/internal/service/networkmanager/transit_gateway_registration_test.go +++ b/internal/service/networkmanager/transit_gateway_registration_test.go @@ -16,11 +16,26 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -func TestAccNetworkManageTransitGatewayRegistration_basic(t *testing.T) { +func TestAccNetworkManageTransitGatewayRegistration_serial(t *testing.T) { + testCases := map[string]func(t *testing.T){ + "basic": testAccNetworkManageTransitGatewayRegistration_basic, + "disappears": testAccNetworkManageTransitGatewayRegistration_disappears, + "disappears_TransitGateway": testAccNetworkManageTransitGatewayRegistration_disappears_TransitGateway, + } + + for name, tc := range testCases { + tc := tc + t.Run(name, func(t *testing.T) { + tc(t) + }) + } +} + +func testAccNetworkManageTransitGatewayRegistration_basic(t *testing.T) { resourceName := "aws_networkmanager_transit_gateway_registration.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), Providers: acctest.Providers, @@ -41,11 +56,11 @@ func TestAccNetworkManageTransitGatewayRegistration_basic(t *testing.T) { }) } -func TestAccNetworkManageTransitGatewayRegistration_disappears(t *testing.T) { +func testAccNetworkManageTransitGatewayRegistration_disappears(t *testing.T) { resourceName := "aws_networkmanager_transit_gateway_registration.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), Providers: acctest.Providers, @@ -63,12 +78,12 @@ func TestAccNetworkManageTransitGatewayRegistration_disappears(t *testing.T) { }) } -func TestAccNetworkManageTransitGatewayRegistration_disappears_TransitGateway(t *testing.T) { +func testAccNetworkManageTransitGatewayRegistration_disappears_TransitGateway(t *testing.T) { resourceName := "aws_networkmanager_transit_gateway_registration.test" transitGatewayResourceName := "aws_ec2_transit_gateway.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), Providers: acctest.Providers, From 90e2e50f253ced1ee8bbeaf7b374a7312cb4bbf5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 12:24:48 -0500 Subject: [PATCH 090/229] r/aws_networkmanager_transit_gateway_registration: Add cross-Region acceptance test. Acceptance test output: % make testacc TESTS=TestAccNetworkManageTransitGatewayRegistration_serial/crossRegion PKG=networkmanager ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/networkmanager/... -v -count 1 -parallel 20 -run='TestAccNetworkManageTransitGatewayRegistration_serial/crossRegion' -timeout 180m === RUN TestAccNetworkManageTransitGatewayRegistration_serial === RUN TestAccNetworkManageTransitGatewayRegistration_serial/crossRegion --- PASS: TestAccNetworkManageTransitGatewayRegistration_serial (274.21s) --- PASS: TestAccNetworkManageTransitGatewayRegistration_serial/crossRegion (274.21s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 277.694s --- .../transit_gateway_registration_test.go | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/internal/service/networkmanager/transit_gateway_registration_test.go b/internal/service/networkmanager/transit_gateway_registration_test.go index 7f0b2c0c859..06d82f546d0 100644 --- a/internal/service/networkmanager/transit_gateway_registration_test.go +++ b/internal/service/networkmanager/transit_gateway_registration_test.go @@ -8,6 +8,7 @@ import ( "github.com/aws/aws-sdk-go/service/networkmanager" 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/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" @@ -21,6 +22,7 @@ func TestAccNetworkManageTransitGatewayRegistration_serial(t *testing.T) { "basic": testAccNetworkManageTransitGatewayRegistration_basic, "disappears": testAccNetworkManageTransitGatewayRegistration_disappears, "disappears_TransitGateway": testAccNetworkManageTransitGatewayRegistration_disappears_TransitGateway, + "crossRegion": testAccNetworkManageTransitGatewayRegistration_crossRegion, } for name, tc := range testCases { @@ -101,6 +103,32 @@ func testAccNetworkManageTransitGatewayRegistration_disappears_TransitGateway(t }) } +func testAccNetworkManageTransitGatewayRegistration_crossRegion(t *testing.T) { + resourceName := "aws_networkmanager_transit_gateway_registration.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + var providers []*schema.Provider + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); acctest.PreCheckMultipleRegion(t, 2) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + ProviderFactories: acctest.FactoriesAlternate(&providers), + CheckDestroy: testAccCheckTransitGatewayRegistrationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTransitGatewayRegistrationCrossRegionConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckTransitGatewayRegistrationExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccCheckTransitGatewayRegistrationDestroy(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn @@ -179,3 +207,26 @@ resource "aws_networkmanager_transit_gateway_registration" "test" { } `, rName) } + +func testAccTransitGatewayRegistrationCrossRegionConfig(rName string) string { + return acctest.ConfigCompose(acctest.ConfigAlternateRegionProvider(), fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_ec2_transit_gateway" "test" { + provider = "awsalternate" + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_transit_gateway_registration" "test" { + global_network_id = aws_networkmanager_global_network.test.id + transit_gateway_arn = aws_ec2_transit_gateway.test.arn +} +`, rName)) +} From 11a0a14b8bce9711f86b090c924558b653bd13ba Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 13:44:44 -0500 Subject: [PATCH 091/229] d/aws_networkmanager_devices: Add optional 'site_id' argument. --- .../service/networkmanager/devices_data_source.go | 14 ++++++++++++-- .../docs/d/networkmanager_devices.html.markdown | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/internal/service/networkmanager/devices_data_source.go b/internal/service/networkmanager/devices_data_source.go index 5571da3386b..0e65de24e41 100644 --- a/internal/service/networkmanager/devices_data_source.go +++ b/internal/service/networkmanager/devices_data_source.go @@ -25,6 +25,10 @@ func DataSourceDevices() *schema.Resource { Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, + "site_id": { + Type: schema.TypeString, + Optional: true, + }, "tags": tftags.TagsSchema(), }, } @@ -35,9 +39,15 @@ func dataSourceDevicesRead(ctx context.Context, d *schema.ResourceData, meta int ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig tagsToMatch := tftags.New(d.Get("tags").(map[string]interface{})).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) - output, err := FindDevices(ctx, conn, &networkmanager.GetDevicesInput{ + input := &networkmanager.GetDevicesInput{ GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), - }) + } + + if v, ok := d.GetOk("site_id"); ok { + input.SiteId = aws.String(v.(string)) + } + + output, err := FindDevices(ctx, conn, input) if err != nil { return diag.Errorf("error listing Network Manager Devices: %s", err) diff --git a/website/docs/d/networkmanager_devices.html.markdown b/website/docs/d/networkmanager_devices.html.markdown index d549a91da63..68b7666008b 100644 --- a/website/docs/d/networkmanager_devices.html.markdown +++ b/website/docs/d/networkmanager_devices.html.markdown @@ -25,6 +25,7 @@ data "aws_networkmanager_devices" "example" { ## Argument Reference * `global_network_id` - (Required) The ID of the Global Network of the devices to retrieve. +* `site_id` - (Optional) The ID of the site of the devices to retrieve. * `tags` - (Optional) Restricts the list to the devices with these tags. ## Attributes Reference From 1a87bb2ea8f943ca1f95a9839280fab1fb5016cb Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 13:50:28 -0500 Subject: [PATCH 092/229] 'hcl' -> 'terraform' for examples. --- website/docs/d/networkmanager_device.html.markdown | 2 +- website/docs/d/networkmanager_devices.html.markdown | 2 +- website/docs/d/networkmanager_global_network.html.markdown | 2 +- website/docs/d/networkmanager_global_networks.html.markdown | 2 +- website/docs/d/networkmanager_site.html.markdown | 2 +- website/docs/d/networkmanager_sites.html.markdown | 2 +- website/docs/r/networkmanager_device.html.markdown | 2 +- website/docs/r/networkmanager_site.html.markdown | 2 +- .../r/networkmanager_transit_gateway_registration.html.markdown | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/website/docs/d/networkmanager_device.html.markdown b/website/docs/d/networkmanager_device.html.markdown index 41f31ee0cad..f4da561d672 100644 --- a/website/docs/d/networkmanager_device.html.markdown +++ b/website/docs/d/networkmanager_device.html.markdown @@ -12,7 +12,7 @@ Retrieve information about a device. ## Example Usage -```hcl +```terraform data "aws_networkmanager_device" "example" { global_network_id_id = var.global_network_id device_id = var.device_id diff --git a/website/docs/d/networkmanager_devices.html.markdown b/website/docs/d/networkmanager_devices.html.markdown index 68b7666008b..61aa42218d7 100644 --- a/website/docs/d/networkmanager_devices.html.markdown +++ b/website/docs/d/networkmanager_devices.html.markdown @@ -12,7 +12,7 @@ Retrieve information about devices. ## Example Usage -```hcl +```terraform data "aws_networkmanager_devices" "example" { global_network_id = var.global_network_id diff --git a/website/docs/d/networkmanager_global_network.html.markdown b/website/docs/d/networkmanager_global_network.html.markdown index bb742693337..65f90a98596 100644 --- a/website/docs/d/networkmanager_global_network.html.markdown +++ b/website/docs/d/networkmanager_global_network.html.markdown @@ -12,7 +12,7 @@ Retrieve information about a global network. ## Example Usage -```hcl +```terraform data "aws_networkmanager_global_network" "example" { global_network_id = var.global_network_id } diff --git a/website/docs/d/networkmanager_global_networks.html.markdown b/website/docs/d/networkmanager_global_networks.html.markdown index 668487647a8..e2d8f5c01c4 100644 --- a/website/docs/d/networkmanager_global_networks.html.markdown +++ b/website/docs/d/networkmanager_global_networks.html.markdown @@ -12,7 +12,7 @@ Retrieve information about global networks. ## Example Usage -```hcl +```terraform data "aws_networkmanager_global_networks" "example" { tags = { Env = "test" diff --git a/website/docs/d/networkmanager_site.html.markdown b/website/docs/d/networkmanager_site.html.markdown index 4e20090ac0e..fdead78104c 100644 --- a/website/docs/d/networkmanager_site.html.markdown +++ b/website/docs/d/networkmanager_site.html.markdown @@ -12,7 +12,7 @@ Retrieve information about a site. ## Example Usage -```hcl +```terraform data " aws_networkmanager_site" "example" { global_network_id = var.global_network_id site_id = var.site_id diff --git a/website/docs/d/networkmanager_sites.html.markdown b/website/docs/d/networkmanager_sites.html.markdown index 936ce6a718a..04854fe1ebc 100644 --- a/website/docs/d/networkmanager_sites.html.markdown +++ b/website/docs/d/networkmanager_sites.html.markdown @@ -12,7 +12,7 @@ Retrieve information about sites. ## Example Usage -```hcl +```terraform data "aws_networkmanager_sites" "example" { global_network_id = var.global_network_id diff --git a/website/docs/r/networkmanager_device.html.markdown b/website/docs/r/networkmanager_device.html.markdown index fbdf012a358..b7c37f5fe88 100644 --- a/website/docs/r/networkmanager_device.html.markdown +++ b/website/docs/r/networkmanager_device.html.markdown @@ -13,7 +13,7 @@ the location of the site is used for visualization in the Network Manager consol ## Example Usage -```hcl +```terraform resource "aws_networkmanager_global_network" "example" { } diff --git a/website/docs/r/networkmanager_site.html.markdown b/website/docs/r/networkmanager_site.html.markdown index b686e2f3911..848913058cd 100644 --- a/website/docs/r/networkmanager_site.html.markdown +++ b/website/docs/r/networkmanager_site.html.markdown @@ -12,7 +12,7 @@ Creates a site in a global network. ## Example Usage -```hcl +```terraform resource "aws_networkmanager_global_network" "example" { } diff --git a/website/docs/r/networkmanager_transit_gateway_registration.html.markdown b/website/docs/r/networkmanager_transit_gateway_registration.html.markdown index 596883e4508..b2e53614ea7 100644 --- a/website/docs/r/networkmanager_transit_gateway_registration.html.markdown +++ b/website/docs/r/networkmanager_transit_gateway_registration.html.markdown @@ -14,7 +14,7 @@ You cannot register a transit gateway in more than one global network. ## Example Usage -```hcl +```terraform resource "aws_networkmanager_global_network" "example" { description = "example" } From f4d30b99b3c8b8a786fee0e19068e15816f24079 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 14:12:13 -0500 Subject: [PATCH 093/229] Additional argument validation. --- internal/service/networkmanager/device.go | 41 ++++++++++++++--------- internal/service/networkmanager/site.go | 15 +++++---- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/internal/service/networkmanager/device.go b/internal/service/networkmanager/device.go index 8d8221b2247..daaf34999ea 100644 --- a/internal/service/networkmanager/device.go +++ b/internal/service/networkmanager/device.go @@ -14,6 +14,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" @@ -63,8 +64,9 @@ func ResourceDevice() *schema.Resource { Computed: true, }, "description": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 256), }, "global_network_id": { Type: schema.TypeString, @@ -78,27 +80,32 @@ func ResourceDevice() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "address": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 256), }, "latitude": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 256), }, "longitude": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 256), }, }, }, }, "model": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 128), }, "serial_number": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 128), }, "site_id": { Type: schema.TypeString, @@ -107,12 +114,14 @@ func ResourceDevice() *schema.Resource { "tags": tftags.TagsSchema(), "tags_all": tftags.TagsSchemaComputed(), "type": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 256), }, "vendor": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 128), }, }, } diff --git a/internal/service/networkmanager/site.go b/internal/service/networkmanager/site.go index 482f35fff24..d1a7c6d71c4 100644 --- a/internal/service/networkmanager/site.go +++ b/internal/service/networkmanager/site.go @@ -80,16 +80,19 @@ func ResourceSite() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "address": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 256), }, "latitude": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 256), }, "longitude": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 256), }, }, }, From 86ccb8b9b79f80cb9105269b4c630120741d46ca Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 14:51:19 -0500 Subject: [PATCH 094/229] r/aws_networkmanager_device: Add `aws_location` argument. Acceptance test output: % make testacc TESTS=TestAccNetworkManagerDevice_ PKG=networkmanager ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/networkmanager/... -v -count 1 -parallel 20 -run='TestAccNetworkManagerDevice_' -timeout 180m === RUN TestAccNetworkManagerDevice_basic === PAUSE TestAccNetworkManagerDevice_basic === RUN TestAccNetworkManagerDevice_disapears === PAUSE TestAccNetworkManagerDevice_disapears === RUN TestAccNetworkManagerDevice_tags === PAUSE TestAccNetworkManagerDevice_tags === RUN TestAccNetworkManagerDevice_allAttributes === PAUSE TestAccNetworkManagerDevice_allAttributes === RUN TestAccNetworkManagerDevice_awsLocation === PAUSE TestAccNetworkManagerDevice_awsLocation === CONT TestAccNetworkManagerDevice_basic === CONT TestAccNetworkManagerDevice_allAttributes === CONT TestAccNetworkManagerDevice_tags === CONT TestAccNetworkManagerDevice_awsLocation === CONT TestAccNetworkManagerDevice_disapears --- PASS: TestAccNetworkManagerDevice_disapears (22.75s) --- PASS: TestAccNetworkManagerDevice_basic (25.63s) --- PASS: TestAccNetworkManagerDevice_allAttributes (42.33s) --- PASS: TestAccNetworkManagerDevice_awsLocation (43.27s) --- PASS: TestAccNetworkManagerDevice_tags (49.61s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 53.821s --- internal/service/networkmanager/device.go | 71 +++++++++++ .../service/networkmanager/device_test.go | 120 ++++++++++++++++++ internal/service/networkmanager/site.go | 6 +- .../r/networkmanager_device.html.markdown | 34 ++--- 4 files changed, 211 insertions(+), 20 deletions(-) diff --git a/internal/service/networkmanager/device.go b/internal/service/networkmanager/device.go index daaf34999ea..79a594b4905 100644 --- a/internal/service/networkmanager/device.go +++ b/internal/service/networkmanager/device.go @@ -63,6 +63,26 @@ func ResourceDevice() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "aws_location": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "subnet_arn": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: verify.ValidARN, + ConflictsWith: []string{"aws_location.0.zone"}, + }, + "zone": { + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"aws_location.0.subnet_arn"}, + }, + }, + }, + }, "description": { Type: schema.TypeString, Optional: true, @@ -142,6 +162,10 @@ func resourceDeviceCreate(ctx context.Context, d *schema.ResourceData, meta inte input.Description = aws.String(v.(string)) } + if v, ok := d.GetOk("aws_location"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.AWSLocation = expandAWSLocation(v.([]interface{})[0].(map[string]interface{})) + } + if v, ok := d.GetOk("location"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { input.Location = expandLocation(v.([]interface{})[0].(map[string]interface{})) } @@ -205,6 +229,13 @@ func resourceDeviceRead(ctx context.Context, d *schema.ResourceData, meta interf } d.Set("arn", device.DeviceArn) + if device.AWSLocation != nil { + if err := d.Set("aws_location", []interface{}{flattenAWSLocation(device.AWSLocation)}); err != nil { + return diag.Errorf("error setting aws_location: %s", err) + } + } else { + d.Set("aws_location", nil) + } d.Set("description", device.Description) if device.Location != nil { if err := d.Set("location", []interface{}{flattenLocation(device.Location)}); err != nil { @@ -249,6 +280,10 @@ func resourceDeviceUpdate(ctx context.Context, d *schema.ResourceData, meta inte Vendor: aws.String(d.Get("vendor").(string)), } + if v, ok := d.GetOk("aws_location"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.AWSLocation = expandAWSLocation(v.([]interface{})[0].(map[string]interface{})) + } + if v, ok := d.GetOk("location"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { input.Location = expandLocation(v.([]interface{})[0].(map[string]interface{})) } @@ -441,3 +476,39 @@ func waitDeviceUpdated(ctx context.Context, conn *networkmanager.NetworkManager, return nil, err } + +func expandAWSLocation(tfMap map[string]interface{}) *networkmanager.AWSLocation { + if tfMap == nil { + return nil + } + + apiObject := &networkmanager.AWSLocation{} + + if v, ok := tfMap["subnet_arn"].(string); ok { + apiObject.SubnetArn = aws.String(v) + } + + if v, ok := tfMap["zone"].(string); ok { + apiObject.Zone = aws.String(v) + } + + return apiObject +} + +func flattenAWSLocation(apiObject *networkmanager.AWSLocation) map[string]interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{} + + if v := apiObject.SubnetArn; v != nil { + tfMap["subnet_arn"] = aws.StringValue(v) + } + + if v := apiObject.Zone; v != nil { + tfMap["zone"] = aws.StringValue(v) + } + + return tfMap +} diff --git a/internal/service/networkmanager/device_test.go b/internal/service/networkmanager/device_test.go index 5b6594a6333..2b2009155dc 100644 --- a/internal/service/networkmanager/device_test.go +++ b/internal/service/networkmanager/device_test.go @@ -30,6 +30,7 @@ func TestAccNetworkManagerDevice_basic(t *testing.T) { Check: resource.ComposeAggregateTestCheckFunc( testAccCheckDeviceExists(resourceName), resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "aws_location.#", "0"), resource.TestCheckResourceAttr(resourceName, "description", ""), resource.TestCheckResourceAttr(resourceName, "location.#", "0"), resource.TestCheckResourceAttr(resourceName, "model", ""), @@ -171,6 +172,45 @@ func TestAccNetworkManagerDevice_allAttributes(t *testing.T) { }) } +func TestAccNetworkManagerDevice_awsLocation(t *testing.T) { + resourceName := "aws_networkmanager_device.test" + subnetResourceName := "aws_subnet.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckDeviceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDeviceAWSLocationConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckDeviceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "aws_location.#", "1"), + resource.TestCheckResourceAttrPair(resourceName, "aws_location.0.subnet_arn", subnetResourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "aws_location.0.zone", ""), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccDeviceImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, + { + Config: testAccDeviceAWSLocationUpdatedConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckDeviceExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "aws_location.#", "1"), + resource.TestCheckResourceAttr(resourceName, "aws_location.0.subnet_arn", ""), + resource.TestCheckResourceAttrPair(resourceName, "aws_location.0.zone", subnetResourceName, "availability_zone"), + ), + }, + }, + }) +} + func testAccCheckDeviceDestroy(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn @@ -363,6 +403,86 @@ resource "aws_networkmanager_device" "test" { `, rName) } +func testAccDeviceAWSLocationConfig(rName string) string { + return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptInDefaultExclude(), fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" + + tags = { + Name = %[1]q + } +} + +resource "aws_subnet" "test" { + availability_zone = data.aws_availability_zones.available.names[0] + cidr_block = "10.0.0.0/24" + vpc_id = aws_vpc.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_device" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + aws_location { + subnet_arn = aws_subnet.test.arn + } + + tags = { + Name = %[1]q + } +} +`, rName)) +} + +func testAccDeviceAWSLocationUpdatedConfig(rName string) string { + return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptInDefaultExclude(), fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" + + tags = { + Name = %[1]q + } +} + +resource "aws_subnet" "test" { + availability_zone = data.aws_availability_zones.available.names[0] + cidr_block = "10.0.0.0/24" + vpc_id = aws_vpc.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_device" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + aws_location { + zone = aws_subnet.test.availability_zone + } + + tags = { + Name = %[1]q + } +} +`, rName)) +} + func testAccDeviceImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { return func(s *terraform.State) (string, error) { rs, ok := s.RootModule().Resources[resourceName] diff --git a/internal/service/networkmanager/site.go b/internal/service/networkmanager/site.go index d1a7c6d71c4..00711f93930 100644 --- a/internal/service/networkmanager/site.go +++ b/internal/service/networkmanager/site.go @@ -409,15 +409,15 @@ func expandLocation(tfMap map[string]interface{}) *networkmanager.Location { apiObject := &networkmanager.Location{} - if v, ok := tfMap["address"].(string); ok && v != "" { + if v, ok := tfMap["address"].(string); ok { apiObject.Address = aws.String(v) } - if v, ok := tfMap["latitude"].(string); ok && v != "" { + if v, ok := tfMap["latitude"].(string); ok { apiObject.Latitude = aws.String(v) } - if v, ok := tfMap["longitude"].(string); ok && v != "" { + if v, ok := tfMap["longitude"].(string); ok { apiObject.Longitude = aws.String(v) } diff --git a/website/docs/r/networkmanager_device.html.markdown b/website/docs/r/networkmanager_device.html.markdown index b7c37f5fe88..64868922ad0 100644 --- a/website/docs/r/networkmanager_device.html.markdown +++ b/website/docs/r/networkmanager_device.html.markdown @@ -14,13 +14,6 @@ the location of the site is used for visualization in the Network Manager consol ## Example Usage ```terraform -resource "aws_networkmanager_global_network" "example" { -} - -resource "aws_networkmanager_site" "example" { - global_network_id = aws_networkmanager_global_network.example.id -} - resource "aws_networkmanager_device" "example" { global_network_id = aws_networkmanager_global_network.example.id site_id = aws_networkmanager_site.example.id @@ -31,27 +24,34 @@ resource "aws_networkmanager_device" "example" { The following arguments are supported: -* `global_network_id` - (Required) The ID of the Global Network to create the device in. -* `description` - (Optional) Description of the device. -* `location` - (Optional) The device location as documented below. -* `type` - (Optional) The type of device. +* `aws_location` - (Optional) The AWS location of the device. Documented below. +* `description` - (Optional) A description of the device. +* `global_network_id` - (Required) The ID of the global network. +* `location` - (Optional) The location of the device. Documented below. * `model` - (Optional) The model of device. * `serial_number` - (Optional) The serial number of the device. -* `site_id` - (Optional) The ID of the Site to create device in. +* `site_id` - (Optional) The ID of the site. +* `tags` - (Optional) Key-value tags for the device. If configured with a provider [`default_tags` configuration block](https://www.terraform.io/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. +* `type` - (Optional) The type of device. * `vendor` - (Optional) The vendor of the device. -* `tags` - (Optional) Key-value tags for the device. + +The `aws_location` object supports the following: + +* `subnet_arn` - (Optional) The Amazon Resource Name (ARN) of the subnet that the device is located in. +* `zone` - (Optional) The Zone that the device is located in. Specify the ID of an Availability Zone, Local Zone, Wavelength Zone, or an Outpost. The `location` object supports the following: -* `address` - (Optional) Address of the location. -* `latitude` - (Optional) Latitude of the location. -* `longitude` - (Optional) Longitude of the location. +* `address` - (Optional) The physical address. +* `latitude` - (Optional) The latitude. +* `longitude` - (Optional) The longitude. ## Attributes Reference In addition to all arguments above, the following attributes are exported: -* `arn` - Device Amazon Resource Name (ARN) +* `arn` - The Amazon Resource Name (ARN) of the device. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](https://www.terraform.io/docs/providers/aws/index.html#default_tags-configuration-block). ## Import From a0bedad3b0f2fefb3f979b6d1fefdeadfe0fcffd Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 14:59:17 -0500 Subject: [PATCH 095/229] d/aws_networkmanager_device: Add `aws_location` attribute. Acceptance test output: % make testacc TESTS=TestAccNetworkManagerDeviceDataSource_ PKG=networkmanager ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/networkmanager/... -v -count 1 -parallel 20 -run='TestAccNetworkManagerDeviceDataSource_' -timeout 180m === RUN TestAccNetworkManagerDeviceDataSource_basic === PAUSE TestAccNetworkManagerDeviceDataSource_basic === CONT TestAccNetworkManagerDeviceDataSource_basic --- PASS: TestAccNetworkManagerDeviceDataSource_basic (20.99s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 24.873s --- .../networkmanager/device_data_source.go | 29 +++++++++++++++++-- .../networkmanager/device_data_source_test.go | 1 + .../networkmanager/site_data_source.go | 6 ++-- .../d/networkmanager_device.html.markdown | 25 ++++++++++------ 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/internal/service/networkmanager/device_data_source.go b/internal/service/networkmanager/device_data_source.go index acd366c9777..2c3f6011848 100644 --- a/internal/service/networkmanager/device_data_source.go +++ b/internal/service/networkmanager/device_data_source.go @@ -18,6 +18,22 @@ func DataSourceDevice() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "aws_location": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "subnet_arn": { + Type: schema.TypeString, + Computed: true, + }, + "zone": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, "description": { Type: schema.TypeString, Computed: true, @@ -37,15 +53,15 @@ func DataSourceDevice() *schema.Resource { Schema: map[string]*schema.Schema{ "address": { Type: schema.TypeString, - Optional: true, + Computed: true, }, "latitude": { Type: schema.TypeString, - Optional: true, + Computed: true, }, "longitude": { Type: schema.TypeString, - Optional: true, + Computed: true, }, }, }, @@ -89,6 +105,13 @@ func dataSourceDeviceRead(ctx context.Context, d *schema.ResourceData, meta inte d.SetId(deviceID) d.Set("arn", device.DeviceArn) + if device.AWSLocation != nil { + if err := d.Set("aws_location", []interface{}{flattenAWSLocation(device.AWSLocation)}); err != nil { + return diag.Errorf("error setting aws_location: %s", err) + } + } else { + d.Set("aws_location", nil) + } d.Set("description", device.Description) d.Set("device_id", device.DeviceId) if device.Location != nil { diff --git a/internal/service/networkmanager/device_data_source_test.go b/internal/service/networkmanager/device_data_source_test.go index b621d20a537..cbc019cd27f 100644 --- a/internal/service/networkmanager/device_data_source_test.go +++ b/internal/service/networkmanager/device_data_source_test.go @@ -24,6 +24,7 @@ func TestAccNetworkManagerDeviceDataSource_basic(t *testing.T) { Config: testAccDeviceDataSourceConfig(rName), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(dataSourceName, "aws_location.#", resourceName, "aws_location.#"), resource.TestCheckResourceAttrPair(dataSourceName, "description", resourceName, "description"), resource.TestCheckResourceAttrPair(dataSourceName, "device_id", resourceName, "id"), resource.TestCheckResourceAttrPair(dataSourceName, "global_network_id", resourceName, "global_network_id"), diff --git a/internal/service/networkmanager/site_data_source.go b/internal/service/networkmanager/site_data_source.go index ca90d4f9531..5e6eea2538a 100644 --- a/internal/service/networkmanager/site_data_source.go +++ b/internal/service/networkmanager/site_data_source.go @@ -33,15 +33,15 @@ func DataSourceSite() *schema.Resource { Schema: map[string]*schema.Schema{ "address": { Type: schema.TypeString, - Optional: true, + Computed: true, }, "latitude": { Type: schema.TypeString, - Optional: true, + Computed: true, }, "longitude": { Type: schema.TypeString, - Optional: true, + Computed: true, }, }, }, diff --git a/website/docs/d/networkmanager_device.html.markdown b/website/docs/d/networkmanager_device.html.markdown index f4da561d672..3cf9e6c448a 100644 --- a/website/docs/d/networkmanager_device.html.markdown +++ b/website/docs/d/networkmanager_device.html.markdown @@ -21,24 +21,31 @@ data "aws_networkmanager_device" "example" { ## Argument Reference -* `device_id` - (Required) The id of the specific device to retrieve. -* `global_network_id` - (Required) The ID of the Global Network of the device to retrieve. +* `device_id` - (Required) The ID of the device. +* `global_network_id` - (Required) The ID of the global network. ## Attributes Reference In addition to all arguments above, the following attributes are exported: -* `description` - Description of the device. -* `location` - The device location as documented below. -* `type` - The type of device. +* `arn` - The Amazon Resource Name (ARN) of the device. +* `aws_location` - The AWS location of the device. Documented below. +* `description` - A description of the device. +* `location` - The location of the device. Documented below. * `model` - The model of device. * `serial_number` - The serial number of the device. -* `site_id` - The site of the device. +* `site_id` - The ID of the site. * `tags` - Key-value tags for the device. +* `type` - The type of device. * `vendor` - The vendor of the device. +The `aws_location` object supports the following: + +* `subnet_arn` - The Amazon Resource Name (ARN) of the subnet that the device is located in. +* `zone` - The Zone that the device is located in. + The `location` object supports the following: -* `address` - Address of the location. -* `latitude` - Latitude of the location. -* `longitude` - Longitude of the location. +* `address` - The physical address. +* `latitude` - The latitude. +* `longitude` - The longitude. From f436a9a642117864b7d72daa13ce2572199d5722 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 15:55:39 -0500 Subject: [PATCH 096/229] r/aws_networkmanager_link: New resource. Acceptance test output: % make testacc TESTS=TestAccNetworkManagerLink_ PKG=networkmanager ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/networkmanager/... -v -count 1 -parallel 20 -run='TestAccNetworkManagerLink_' -timeout 180m === RUN TestAccNetworkManagerLink_basic === PAUSE TestAccNetworkManagerLink_basic === RUN TestAccNetworkManagerLink_disappears === PAUSE TestAccNetworkManagerLink_disappears === RUN TestAccNetworkManagerLink_tags === PAUSE TestAccNetworkManagerLink_tags === RUN TestAccNetworkManagerLink_allAttributes === PAUSE TestAccNetworkManagerLink_allAttributes === CONT TestAccNetworkManagerLink_basic === CONT TestAccNetworkManagerLink_tags === CONT TestAccNetworkManagerLink_allAttributes === CONT TestAccNetworkManagerLink_disappears --- PASS: TestAccNetworkManagerLink_disappears (22.55s) --- PASS: TestAccNetworkManagerLink_basic (25.50s) --- PASS: TestAccNetworkManagerLink_allAttributes (38.78s) --- PASS: TestAccNetworkManagerLink_tags (50.17s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 54.000s --- .changelog/13251.txt | 4 + internal/provider/provider.go | 1 + internal/service/networkmanager/device.go | 1 + internal/service/networkmanager/link.go | 447 ++++++++++++++++++ internal/service/networkmanager/link_test.go | 384 +++++++++++++++ internal/service/networkmanager/site.go | 1 + .../docs/r/networkmanager_link.html.markdown | 59 +++ 7 files changed, 897 insertions(+) create mode 100644 internal/service/networkmanager/link.go create mode 100644 internal/service/networkmanager/link_test.go create mode 100644 website/docs/r/networkmanager_link.html.markdown diff --git a/.changelog/13251.txt b/.changelog/13251.txt index 8917cedbd05..a121af84bdd 100644 --- a/.changelog/13251.txt +++ b/.changelog/13251.txt @@ -14,6 +14,10 @@ aws_networkmanager_device aws_networkmanager_transit_gateway_registration ``` +```release-note:new-resource +aws_networkmanager_link +``` + ```release-note:new-data-source aws_networkmanager_global_network ``` diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 9e9a6aa58ab..dd445f44c99 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1586,6 +1586,7 @@ func Provider() *schema.Provider { "aws_networkmanager_device": networkmanager.ResourceDevice(), "aws_networkmanager_global_network": networkmanager.ResourceGlobalNetwork(), + "aws_networkmanager_link": networkmanager.ResourceLink(), "aws_networkmanager_site": networkmanager.ResourceSite(), "aws_networkmanager_transit_gateway_registration": networkmanager.ResourceTransitGatewayRegistration(), diff --git a/internal/service/networkmanager/device.go b/internal/service/networkmanager/device.go index 79a594b4905..f767fdd45e1 100644 --- a/internal/service/networkmanager/device.go +++ b/internal/service/networkmanager/device.go @@ -237,6 +237,7 @@ func resourceDeviceRead(ctx context.Context, d *schema.ResourceData, meta interf d.Set("aws_location", nil) } d.Set("description", device.Description) + d.Set("global_network_id", device.GlobalNetworkId) if device.Location != nil { if err := d.Set("location", []interface{}{flattenLocation(device.Location)}); err != nil { return diag.Errorf("error setting location: %s", err) diff --git a/internal/service/networkmanager/link.go b/internal/service/networkmanager/link.go new file mode 100644 index 00000000000..c633262e4b1 --- /dev/null +++ b/internal/service/networkmanager/link.go @@ -0,0 +1,447 @@ +package networkmanager + +import ( + "context" + "fmt" + "log" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/arn" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/internal/verify" +) + +func ResourceLink() *schema.Resource { + return &schema.Resource{ + CreateWithoutTimeout: resourceLinkCreate, + ReadWithoutTimeout: resourceLinkRead, + UpdateWithoutTimeout: resourceLinkUpdate, + DeleteWithoutTimeout: resourceLinkDelete, + + Importer: &schema.ResourceImporter{ + StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + parsedARN, err := arn.Parse(d.Id()) + + if err != nil { + return nil, fmt.Errorf("error parsing ARN (%s): %w", d.Id(), err) + } + + // See https://docs.aws.amazon.com/service-authorization/latest/reference/list_networkmanager.html#networkmanager-resources-for-iam-policies. + resourceParts := strings.Split(parsedARN.Resource, "/") + + if actual, expected := len(resourceParts), 3; actual < expected { + return nil, fmt.Errorf("expected at least %d resource parts in ARN (%s), got: %d", expected, d.Id(), actual) + } + + d.SetId(resourceParts[2]) + d.Set("global_network_id", resourceParts[1]) + + return []*schema.ResourceData{d}, nil + }, + }, + + CustomizeDiff: verify.SetTagsDiff, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Update: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "bandwidth": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "download_speed": { + Type: schema.TypeInt, + Optional: true, + }, + "upload_speed": { + Type: schema.TypeInt, + Optional: true, + }, + }, + }, + }, + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 256), + }, + "global_network_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "provider_name": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 128), + }, + "site_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "tags": tftags.TagsSchema(), + "tags_all": tftags.TagsSchemaComputed(), + "type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 128), + }, + }, + } +} + +func resourceLinkCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{}))) + + globalNetworkID := d.Get("global_network_id").(string) + input := &networkmanager.CreateLinkInput{ + GlobalNetworkId: aws.String(globalNetworkID), + SiteId: aws.String(d.Get("site_id").(string)), + } + + if v, ok := d.GetOk("bandwidth"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.Bandwidth = expandBandwidth(v.([]interface{})[0].(map[string]interface{})) + } + + if v, ok := d.GetOk("description"); ok { + input.Description = aws.String(v.(string)) + } + + if v, ok := d.GetOk("provider_name"); ok { + input.Provider = aws.String(v.(string)) + } + + if v, ok := d.GetOk("type"); ok { + input.Type = aws.String(v.(string)) + } + + if len(tags) > 0 { + input.Tags = Tags(tags.IgnoreAWS()) + } + + log.Printf("[DEBUG] Creating Network Manager Link: %s", input) + output, err := conn.CreateLinkWithContext(ctx, input) + + if err != nil { + return diag.Errorf("error creating Network Manager Link: %s", err) + } + + d.SetId(aws.StringValue(output.Link.LinkId)) + + if _, err := waitLinkCreated(ctx, conn, globalNetworkID, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { + return diag.Errorf("error waiting for Network Manager Link (%s) create: %s", d.Id(), err) + } + + return resourceLinkRead(ctx, d, meta) +} + +func resourceLinkRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig + + globalNetworkID := d.Get("global_network_id").(string) + link, err := FindLinkByTwoPartKey(ctx, conn, globalNetworkID, d.Id()) + + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Network Manager Link %s not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return diag.Errorf("error reading Network Manager Link (%s): %s", d.Id(), err) + } + + d.Set("arn", link.LinkArn) + if link.Bandwidth != nil { + if err := d.Set("bandwidth", []interface{}{flattenBandwidth(link.Bandwidth)}); err != nil { + return diag.Errorf("error setting bandwidth: %s", err) + } + } else { + d.Set("bandwidth", nil) + } + d.Set("description", link.Description) + d.Set("global_network_id", link.GlobalNetworkId) + d.Set("provider_name", link.Provider) + d.Set("site_id", link.SiteId) + d.Set("type", link.Type) + + tags := KeyValueTags(link.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return diag.Errorf("error setting tags: %s", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return diag.Errorf("error setting tags_all: %s", err) + } + + return nil +} + +func resourceLinkUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + if d.HasChangesExcept("tags", "tags_all") { + globalNetworkID := d.Get("global_network_id").(string) + input := &networkmanager.UpdateLinkInput{ + Description: aws.String(d.Get("description").(string)), + GlobalNetworkId: aws.String(globalNetworkID), + LinkId: aws.String(d.Id()), + Provider: aws.String(d.Get("provider_name").(string)), + Type: aws.String(d.Get("type").(string)), + } + + if v, ok := d.GetOk("bandwidth"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.Bandwidth = expandBandwidth(v.([]interface{})[0].(map[string]interface{})) + } + + log.Printf("[DEBUG] Updating Network Manager Link: %s", input) + _, err := conn.UpdateLinkWithContext(ctx, input) + + if err != nil { + return diag.Errorf("error updating Network Manager Link (%s): %s", d.Id(), err) + } + + if _, err := waitLinkUpdated(ctx, conn, globalNetworkID, d.Id(), d.Timeout(schema.TimeoutUpdate)); err != nil { + return diag.Errorf("error waiting for Network Manager Link (%s) update: %s", d.Id(), err) + } + } + + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") + + if err := UpdateTags(conn, d.Get("arn").(string), o, n); err != nil { + return diag.Errorf("error updating Network Manager Link (%s) tags: %s", d.Id(), err) + } + } + + return resourceLinkRead(ctx, d, meta) +} + +func resourceLinkDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + globalNetworkID := d.Get("global_network_id").(string) + + log.Printf("[DEBUG] Deleting Network Manager Link: %s", d.Id()) + _, err := conn.DeleteLinkWithContext(ctx, &networkmanager.DeleteLinkInput{ + GlobalNetworkId: aws.String(globalNetworkID), + LinkId: aws.String(d.Id()), + }) + + if globalNetworkIDNotFoundError(err) || tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeResourceNotFoundException) { + return nil + } + + if err != nil { + return diag.Errorf("error deleting Network Manager Link (%s): %s", d.Id(), err) + } + + if _, err := waitLinkDeleted(ctx, conn, globalNetworkID, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil { + return diag.Errorf("error waiting for Network Manager Link (%s) delete: %s", d.Id(), err) + } + + return nil +} + +func FindLink(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.GetLinksInput) (*networkmanager.Link, error) { + output, err := FindLinks(ctx, conn, input) + + if err != nil { + return nil, err + } + + if len(output) == 0 || output[0] == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } + + return output[0], nil +} + +func FindLinks(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.GetLinksInput) ([]*networkmanager.Link, error) { + var output []*networkmanager.Link + + err := conn.GetLinksPagesWithContext(ctx, input, func(page *networkmanager.GetLinksOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.Links { + if v == nil { + continue + } + + output = append(output, v) + } + + return !lastPage + }) + + if globalNetworkIDNotFoundError(err) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + return output, nil +} + +func FindLinkByTwoPartKey(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, linkID string) (*networkmanager.Link, error) { + input := &networkmanager.GetLinksInput{ + GlobalNetworkId: aws.String(globalNetworkID), + LinkIds: aws.StringSlice([]string{linkID}), + } + + output, err := FindLink(ctx, conn, input) + + if err != nil { + return nil, err + } + + // Eventual consistency check. + if aws.StringValue(output.GlobalNetworkId) != globalNetworkID || aws.StringValue(output.LinkId) != linkID { + return nil, &resource.NotFoundError{ + LastRequest: input, + } + } + + return output, nil +} + +func statusLinkState(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, linkID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + output, err := FindLinkByTwoPartKey(ctx, conn, globalNetworkID, linkID) + + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return output, aws.StringValue(output.State), nil + } +} + +func waitLinkCreated(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, linkID string, timeout time.Duration) (*networkmanager.Link, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.LinkStatePending}, + Target: []string{networkmanager.LinkStateAvailable}, + Timeout: timeout, + Refresh: statusLinkState(ctx, conn, globalNetworkID, linkID), + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*networkmanager.Link); ok { + return output, err + } + + return nil, err +} + +func waitLinkDeleted(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, linkID string, timeout time.Duration) (*networkmanager.Link, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.LinkStateDeleting}, + Target: []string{}, + Timeout: timeout, + Refresh: statusLinkState(ctx, conn, globalNetworkID, linkID), + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*networkmanager.Link); ok { + return output, err + } + + return nil, err +} + +func waitLinkUpdated(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, linkID string, timeout time.Duration) (*networkmanager.Link, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.LinkStateUpdating}, + Target: []string{networkmanager.LinkStateAvailable}, + Timeout: timeout, + Refresh: statusLinkState(ctx, conn, globalNetworkID, linkID), + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*networkmanager.Link); ok { + return output, err + } + + return nil, err +} + +func expandBandwidth(tfMap map[string]interface{}) *networkmanager.Bandwidth { + if tfMap == nil { + return nil + } + + apiObject := &networkmanager.Bandwidth{} + + if v, ok := tfMap["download_speed"].(int); ok && v != 0 { + apiObject.DownloadSpeed = aws.Int64(int64(v)) + } + + if v, ok := tfMap["upload_speed"].(int); ok && v != 0 { + apiObject.UploadSpeed = aws.Int64(int64(v)) + } + + return apiObject +} + +func flattenBandwidth(apiObject *networkmanager.Bandwidth) map[string]interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{} + + if v := apiObject.DownloadSpeed; v != nil { + tfMap["download_speed"] = aws.Int64Value(v) + } + + if v := apiObject.UploadSpeed; v != nil { + tfMap["upload_speed"] = aws.Int64Value(v) + } + + return tfMap +} diff --git a/internal/service/networkmanager/link_test.go b/internal/service/networkmanager/link_test.go new file mode 100644 index 00000000000..cbce42d36c6 --- /dev/null +++ b/internal/service/networkmanager/link_test.go @@ -0,0 +1,384 @@ +package networkmanager_test + +import ( + "context" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/networkmanager" + 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" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tfnetworkmanager "github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" +) + +func TestAccNetworkManagerLink_basic(t *testing.T) { + resourceName := "aws_networkmanager_link.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckLinkDestroy, + Steps: []resource.TestStep{ + { + Config: testAccLinkConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckLinkExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "bandwidth.#", "1"), + resource.TestCheckResourceAttr(resourceName, "bandwidth.0.download_speed", "50"), + resource.TestCheckResourceAttr(resourceName, "bandwidth.0.upload_speed", "10"), + resource.TestCheckResourceAttr(resourceName, "description", ""), + resource.TestCheckResourceAttr(resourceName, "provider_name", ""), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "type", ""), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccLinkImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccNetworkManagerLink_disappears(t *testing.T) { + resourceName := "aws_networkmanager_link.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckLinkDestroy, + Steps: []resource.TestStep{ + { + Config: testAccLinkConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckLinkExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfnetworkmanager.ResourceLink(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccNetworkManagerLink_tags(t *testing.T) { + resourceName := "aws_networkmanager_link.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckLinkDestroy, + Steps: []resource.TestStep{ + { + Config: testAccLinkConfigTags1(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckLinkExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccLinkImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, + { + Config: testAccLinkConfigTags2(rName, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckLinkExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccLinkConfigTags1(rName, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckLinkExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + }, + }) +} + +func TestAccNetworkManagerLink_allAttributes(t *testing.T) { + resourceName := "aws_networkmanager_link.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckLinkDestroy, + Steps: []resource.TestStep{ + { + Config: testAccLinkAllAttributesConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckLinkExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "bandwidth.#", "1"), + resource.TestCheckResourceAttr(resourceName, "bandwidth.0.download_speed", "50"), + resource.TestCheckResourceAttr(resourceName, "bandwidth.0.upload_speed", "10"), + resource.TestCheckResourceAttr(resourceName, "description", "description1"), + resource.TestCheckResourceAttr(resourceName, "provider_name", "provider1"), + resource.TestCheckResourceAttr(resourceName, "type", "type1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccLinkImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, + { + Config: testAccLinkAllAttributesUpdatedConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckLinkExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "bandwidth.#", "1"), + resource.TestCheckResourceAttr(resourceName, "bandwidth.0.download_speed", "75"), + resource.TestCheckResourceAttr(resourceName, "bandwidth.0.upload_speed", "20"), + resource.TestCheckResourceAttr(resourceName, "description", "description2"), + resource.TestCheckResourceAttr(resourceName, "provider_name", "provider2"), + resource.TestCheckResourceAttr(resourceName, "type", "type2"), + ), + }, + }, + }) +} + +func testAccCheckLinkDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_networkmanager_link" { + continue + } + + _, err := tfnetworkmanager.FindLinkByTwoPartKey(context.TODO(), conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) + + if tfresource.NotFound(err) { + continue + } + + if err != nil { + return err + } + + return fmt.Errorf("Network Manager Link %s still exists", rs.Primary.ID) + } + + return nil +} + +func testAccCheckLinkExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No Network Manager Link ID is set") + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn + + _, err := tfnetworkmanager.FindLinkByTwoPartKey(context.TODO(), conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) + + if err != nil { + return err + } + + return nil + } +} + +func testAccLinkConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_link" "test" { + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id + + bandwidth { + download_speed = 50 + upload_speed = 10 + } +} +`, rName) +} + +func testAccLinkConfigTags1(rName, tagKey1, tagValue1 string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_link" "test" { + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id + + bandwidth { + download_speed = 50 + upload_speed = 10 + } + + tags = { + %[2]q = %[3]q + } +} +`, rName, tagKey1, tagValue1) +} + +func testAccLinkConfigTags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_link" "test" { + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id + + bandwidth { + download_speed = 50 + upload_speed = 10 + } + + tags = { + %[2]q = %[3]q + %[4]q = %[5]q + } +} +`, rName, tagKey1, tagValue1, tagKey2, tagValue2) +} + +func testAccLinkAllAttributesConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_link" "test" { + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id + + bandwidth { + download_speed = 50 + upload_speed = 10 + } + + description = "description1" + provider_name = "provider1" + type = "type1" + + tags = { + Name = %[1]q + } +} +`, rName) +} + +func testAccLinkAllAttributesUpdatedConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_link" "test" { + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id + + bandwidth { + download_speed = 75 + upload_speed = 20 + } + + description = "description2" + provider_name = "provider2" + type = "type2" + + tags = { + Name = %[1]q + } +} +`, rName) +} + +func testAccLinkImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("Not found: %s", resourceName) + } + + return rs.Primary.Attributes["arn"], nil + } +} diff --git a/internal/service/networkmanager/site.go b/internal/service/networkmanager/site.go index 00711f93930..edcfa3647d0 100644 --- a/internal/service/networkmanager/site.go +++ b/internal/service/networkmanager/site.go @@ -161,6 +161,7 @@ func resourceSiteRead(ctx context.Context, d *schema.ResourceData, meta interfac d.Set("arn", site.SiteArn) d.Set("description", site.Description) + d.Set("global_network_id", site.GlobalNetworkId) if site.Location != nil { if err := d.Set("location", []interface{}{flattenLocation(site.Location)}); err != nil { return diag.Errorf("error setting location: %s", err) diff --git a/website/docs/r/networkmanager_link.html.markdown b/website/docs/r/networkmanager_link.html.markdown new file mode 100644 index 00000000000..f20b2d96767 --- /dev/null +++ b/website/docs/r/networkmanager_link.html.markdown @@ -0,0 +1,59 @@ +--- +subcategory: "Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_link" +description: |- + Creates a link for a site. +--- + +# Resource: aws_networkmanager_link + +Creates a link for a site. + +## Example Usage + +```terraform +resource "aws_networkmanager_link" "example" { + global_network_id = aws_networkmanager_global_network.example.id + site_id = aws_networkmanager_global_site.example.id + + bandwidth { + upload_speed = 10 + download_speed = 50 + } + + provider_name = "MegaCorp" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `bandwidth` - (Required) The upload speed and download speed in Mbps. Documented below. +* `description` - (Optional) A description of the link. +* `global_network_id` - (Required) The ID of the global network. +* `provider_name` - (Optional) The provider of the link. +* `site_id` - (Required) The ID of the site. +* `tags` - (Optional) Key-value tags for the link. If configured with a provider [`default_tags` configuration block](https://www.terraform.io/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. +* `type` - (Optional) The type of the link. + +The `bandwidth` object supports the following: + +* `download_speed` - (Optional) Download speed in Mbps. +* `upload_speed` - (Optional) Upload speed in Mbps. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - Link Amazon Resource Name (ARN). +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](https://www.terraform.io/docs/providers/aws/index.html#default_tags-configuration-block). + +## Import + +`aws_networkmanager_link` can be imported using the link ARN, e.g. + +``` +$ terraform import aws_networkmanager_site.example arn:aws:networkmanager::123456789012:link/global-network-0d47f6t230mz46dy4/link-444555aaabbb11223 +``` From ea020a08b9d919c2f4123aa296eed09e9990a45e Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 16:01:32 -0500 Subject: [PATCH 097/229] Sweep Links. --- internal/service/networkmanager/sweep.go | 73 ++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/internal/service/networkmanager/sweep.go b/internal/service/networkmanager/sweep.go index bf4750c0fce..2e73b811774 100644 --- a/internal/service/networkmanager/sweep.go +++ b/internal/service/networkmanager/sweep.go @@ -29,6 +29,7 @@ func init() { F: sweepSites, Dependencies: []string{ "aws_networkmanager_device", + "aws_networkmanager_link", }, }) @@ -36,6 +37,11 @@ func init() { Name: "aws_networkmanager_device", F: sweepDevices, }) + + resource.AddTestSweepers("aws_networkmanager_link", &resource.Sweeper{ + Name: "aws_networkmanager_link", + F: sweepLinks, + }) } func sweepGlobalNetworks(region string) error { @@ -214,3 +220,70 @@ func sweepDevices(region string) error { return sweeperErrs.ErrorOrNil() } + +func sweepLinks(region string) error { + client, err := sweep.SharedRegionalSweepClient(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*conns.AWSClient).NetworkManagerConn + input := &networkmanager.DescribeGlobalNetworksInput{} + var sweeperErrs *multierror.Error + sweepResources := make([]*sweep.SweepResource, 0) + + err = conn.DescribeGlobalNetworksPages(input, func(page *networkmanager.DescribeGlobalNetworksOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.GlobalNetworks { + input := &networkmanager.GetLinksInput{ + GlobalNetworkId: v.GlobalNetworkId, + } + + err := conn.GetLinksPages(input, func(page *networkmanager.GetLinksOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.Links { + r := ResourceLink() + d := r.Data(nil) + d.SetId(aws.StringValue(v.LinkId)) + d.Set("global_network_id", v.GlobalNetworkId) + + sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) + } + + return !lastPage + }) + + if sweep.SkipSweepError(err) { + continue + } + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing Network Manager Links (%s): %w", region, err)) + } + } + + return !lastPage + }) + + if sweep.SkipSweepError(err) { + log.Printf("[WARN] Skipping Network Manager Link sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing Network Manager Global Networks (%s): %w", region, err)) + } + + err = sweep.SweepOrchestrator(sweepResources) + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error sweeping Network Manager Links (%s): %w", region, err)) + } + + return sweeperErrs.ErrorOrNil() +} From ea00bf5187433ba2e93b5a0e1e99bcbcea79b4e1 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 16:18:14 -0500 Subject: [PATCH 098/229] Fix terrafmt errors in acceptance test configurations. --- .../service/networkmanager/device_data_source_test.go | 4 ++-- internal/service/networkmanager/device_test.go | 4 ++-- .../service/networkmanager/devices_data_source_test.go | 6 +++--- .../networkmanager/global_network_data_source_test.go | 2 +- internal/service/networkmanager/global_network_test.go | 6 +++--- .../networkmanager/global_networks_data_source_test.go | 4 ++-- internal/service/networkmanager/link_test.go | 4 ++-- internal/service/networkmanager/site_data_source_test.go | 4 ++-- internal/service/networkmanager/site_test.go | 8 ++++---- internal/service/networkmanager/sites_data_source_test.go | 6 +++--- .../networkmanager/transit_gateway_registration_test.go | 8 ++++---- 11 files changed, 28 insertions(+), 28 deletions(-) diff --git a/internal/service/networkmanager/device_data_source_test.go b/internal/service/networkmanager/device_data_source_test.go index cbc019cd27f..50785ab5b80 100644 --- a/internal/service/networkmanager/device_data_source_test.go +++ b/internal/service/networkmanager/device_data_source_test.go @@ -44,7 +44,7 @@ func testAccDeviceDataSourceConfig(rName string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { tags = { - Name = %[1]q + Name = %[1]q } } @@ -64,7 +64,7 @@ resource "aws_networkmanager_device" "test" { } tags = { - Name = %[1]q + Name = %[1]q } } diff --git a/internal/service/networkmanager/device_test.go b/internal/service/networkmanager/device_test.go index 2b2009155dc..dacde8cbb84 100644 --- a/internal/service/networkmanager/device_test.go +++ b/internal/service/networkmanager/device_test.go @@ -302,8 +302,8 @@ resource "aws_networkmanager_device" "test" { global_network_id = aws_networkmanager_global_network.test.id tags = { - %[2]q = %[3]q - %[4]q = %[5]q + %[2]q = %[3]q + %[4]q = %[5]q } } `, rName, tagKey1, tagValue1, tagKey2, tagValue2) diff --git a/internal/service/networkmanager/devices_data_source_test.go b/internal/service/networkmanager/devices_data_source_test.go index 7c6b0a0bdbf..6d53ba0ef9b 100644 --- a/internal/service/networkmanager/devices_data_source_test.go +++ b/internal/service/networkmanager/devices_data_source_test.go @@ -35,7 +35,7 @@ func testAccDevicesDataSourceConfig(rName string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { tags = { - Name = %[1]q + Name = %[1]q } } @@ -43,7 +43,7 @@ resource "aws_networkmanager_device" "test1" { global_network_id = aws_networkmanager_global_network.test.id tags = { - Name = %[1]q + Name = %[1]q } } @@ -61,7 +61,7 @@ data "aws_networkmanager_devices" "by_tags" { global_network_id = aws_networkmanager_global_network.test.id tags = { - Name = %[1]q + Name = %[1]q } depends_on = [aws_networkmanager_device.test1, aws_networkmanager_device.test2] diff --git a/internal/service/networkmanager/global_network_data_source_test.go b/internal/service/networkmanager/global_network_data_source_test.go index afb786d4e0e..f9b46911d78 100644 --- a/internal/service/networkmanager/global_network_data_source_test.go +++ b/internal/service/networkmanager/global_network_data_source_test.go @@ -39,7 +39,7 @@ resource "aws_networkmanager_global_network" "test" { description = "test" tags = { - Name = %[1]q + Name = %[1]q } } diff --git a/internal/service/networkmanager/global_network_test.go b/internal/service/networkmanager/global_network_test.go index 6685cebf065..03491edb683 100644 --- a/internal/service/networkmanager/global_network_test.go +++ b/internal/service/networkmanager/global_network_test.go @@ -195,7 +195,7 @@ func testAccGlobalNetworkConfigTags1(tagKey1, tagValue1 string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { tags = { - %[1]q = %[2]q + %[1]q = %[2]q } } `, tagKey1, tagValue1) @@ -205,8 +205,8 @@ func testAccGlobalNetworkConfigTags2(tagKey1, tagValue1, tagKey2, tagValue2 stri return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { tags = { - %[1]q = %[2]q - %[3]q = %[4]q + %[1]q = %[2]q + %[3]q = %[4]q } } `, tagKey1, tagValue1, tagKey2, tagValue2) diff --git a/internal/service/networkmanager/global_networks_data_source_test.go b/internal/service/networkmanager/global_networks_data_source_test.go index 5fe50b081f8..50622e24266 100644 --- a/internal/service/networkmanager/global_networks_data_source_test.go +++ b/internal/service/networkmanager/global_networks_data_source_test.go @@ -37,7 +37,7 @@ resource "aws_networkmanager_global_network" "test1" { description = "test1" tags = { - Name = %[1]q + Name = %[1]q } } @@ -51,7 +51,7 @@ data "aws_networkmanager_global_networks" "all" { data "aws_networkmanager_global_networks" "by_tags" { tags = { - Name = %[1]q + Name = %[1]q } depends_on = [aws_networkmanager_global_network.test1, aws_networkmanager_global_network.test2] diff --git a/internal/service/networkmanager/link_test.go b/internal/service/networkmanager/link_test.go index cbce42d36c6..6d736f75c2f 100644 --- a/internal/service/networkmanager/link_test.go +++ b/internal/service/networkmanager/link_test.go @@ -293,8 +293,8 @@ resource "aws_networkmanager_link" "test" { } tags = { - %[2]q = %[3]q - %[4]q = %[5]q + %[2]q = %[3]q + %[4]q = %[5]q } } `, rName, tagKey1, tagValue1, tagKey2, tagValue2) diff --git a/internal/service/networkmanager/site_data_source_test.go b/internal/service/networkmanager/site_data_source_test.go index c532abccadc..cbcc25aa5ba 100644 --- a/internal/service/networkmanager/site_data_source_test.go +++ b/internal/service/networkmanager/site_data_source_test.go @@ -39,7 +39,7 @@ func testAccSiteDataSourceConfig(rName string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { tags = { - Name = %[1]q + Name = %[1]q } } @@ -53,7 +53,7 @@ resource "aws_networkmanager_site" "test" { } tags = { - Name = %[1]q + Name = %[1]q } } diff --git a/internal/service/networkmanager/site_test.go b/internal/service/networkmanager/site_test.go index 6ebb0989f4c..28dedc915b1 100644 --- a/internal/service/networkmanager/site_test.go +++ b/internal/service/networkmanager/site_test.go @@ -277,8 +277,8 @@ resource "aws_networkmanager_site" "test" { global_network_id = aws_networkmanager_global_network.test.id tags = { - %[2]q = %[3]q - %[4]q = %[5]q + %[2]q = %[3]q + %[4]q = %[5]q } } `, rName, tagKey1, tagValue1, tagKey2, tagValue2) @@ -317,7 +317,7 @@ resource "aws_networkmanager_site" "test" { location { address = "Stuart, FL" latitude = "27.198" - longitude = "-80.253" + longitude = "-80.253" } tags = { @@ -341,7 +341,7 @@ resource "aws_networkmanager_site" "test" { location { address = "Brisbane, QLD" latitude = "-27.470" - longitude = "153.026" + longitude = "153.026" } tags = { diff --git a/internal/service/networkmanager/sites_data_source_test.go b/internal/service/networkmanager/sites_data_source_test.go index 4f91e04129a..c3b8c52ea9f 100644 --- a/internal/service/networkmanager/sites_data_source_test.go +++ b/internal/service/networkmanager/sites_data_source_test.go @@ -35,7 +35,7 @@ func testAccSitesDataSourceConfig(rName string) string { return fmt.Sprintf(` resource "aws_networkmanager_global_network" "test" { tags = { - Name = %[1]q + Name = %[1]q } } @@ -43,7 +43,7 @@ resource "aws_networkmanager_site" "test1" { global_network_id = aws_networkmanager_global_network.test.id tags = { - Name = %[1]q + Name = %[1]q } } @@ -61,7 +61,7 @@ data "aws_networkmanager_sites" "by_tags" { global_network_id = aws_networkmanager_global_network.test.id tags = { - Name = %[1]q + Name = %[1]q } depends_on = [aws_networkmanager_site.test1, aws_networkmanager_site.test2] diff --git a/internal/service/networkmanager/transit_gateway_registration_test.go b/internal/service/networkmanager/transit_gateway_registration_test.go index 06d82f546d0..30019664a87 100644 --- a/internal/service/networkmanager/transit_gateway_registration_test.go +++ b/internal/service/networkmanager/transit_gateway_registration_test.go @@ -202,8 +202,8 @@ resource "aws_ec2_transit_gateway" "test" { } resource "aws_networkmanager_transit_gateway_registration" "test" { - global_network_id = aws_networkmanager_global_network.test.id - transit_gateway_arn = aws_ec2_transit_gateway.test.arn + global_network_id = aws_networkmanager_global_network.test.id + transit_gateway_arn = aws_ec2_transit_gateway.test.arn } `, rName) } @@ -225,8 +225,8 @@ resource "aws_ec2_transit_gateway" "test" { } resource "aws_networkmanager_transit_gateway_registration" "test" { - global_network_id = aws_networkmanager_global_network.test.id - transit_gateway_arn = aws_ec2_transit_gateway.test.arn + global_network_id = aws_networkmanager_global_network.test.id + transit_gateway_arn = aws_ec2_transit_gateway.test.arn } `, rName)) } From b36b697c36c69e96cd6bcf8c5c857c77193e9fcd Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 16:22:04 -0500 Subject: [PATCH 099/229] Fix tfproviderdocs errors. --- website/docs/r/networkmanager_device.html.markdown | 2 +- website/docs/r/networkmanager_global_network.html.markdown | 2 +- website/docs/r/networkmanager_link.html.markdown | 2 +- .../networkmanager_transit_gateway_registration.html.markdown | 4 ++++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/website/docs/r/networkmanager_device.html.markdown b/website/docs/r/networkmanager_device.html.markdown index 64868922ad0..2214250cc00 100644 --- a/website/docs/r/networkmanager_device.html.markdown +++ b/website/docs/r/networkmanager_device.html.markdown @@ -1,5 +1,5 @@ --- -subcategory: "Transit Gateway Network Manager" +subcategory: "Network Manager" layout: "aws" page_title: "AWS: aws_networkmanager_device" description: |- diff --git a/website/docs/r/networkmanager_global_network.html.markdown b/website/docs/r/networkmanager_global_network.html.markdown index d5ae323e01e..4323aefaa92 100644 --- a/website/docs/r/networkmanager_global_network.html.markdown +++ b/website/docs/r/networkmanager_global_network.html.markdown @@ -12,7 +12,7 @@ Provides a global network resource. ## Example Usage -```hcl +```terraform resource "aws_networkmanager_global_network" "example" { description = "example" } diff --git a/website/docs/r/networkmanager_link.html.markdown b/website/docs/r/networkmanager_link.html.markdown index f20b2d96767..2c9717a0c00 100644 --- a/website/docs/r/networkmanager_link.html.markdown +++ b/website/docs/r/networkmanager_link.html.markdown @@ -55,5 +55,5 @@ In addition to all arguments above, the following attributes are exported: `aws_networkmanager_link` can be imported using the link ARN, e.g. ``` -$ terraform import aws_networkmanager_site.example arn:aws:networkmanager::123456789012:link/global-network-0d47f6t230mz46dy4/link-444555aaabbb11223 +$ terraform import aws_networkmanager_link.example arn:aws:networkmanager::123456789012:link/global-network-0d47f6t230mz46dy4/link-444555aaabbb11223 ``` diff --git a/website/docs/r/networkmanager_transit_gateway_registration.html.markdown b/website/docs/r/networkmanager_transit_gateway_registration.html.markdown index b2e53614ea7..a8eed7cb2d0 100644 --- a/website/docs/r/networkmanager_transit_gateway_registration.html.markdown +++ b/website/docs/r/networkmanager_transit_gateway_registration.html.markdown @@ -34,6 +34,10 @@ The following arguments are supported: * `global_network_id` - (Required) The ID of the Global Network to register to. * `transit_gateway_arn` - (Required) The ARN of the Transit Gateway to register. +## Attributes Reference + +No additional attributes are exported. + ## Import `aws_networkmanager_transit_gateway_registration` can be imported using the global network ID and transit gateway ARN, e.g. From 85c2260b11865e337349a30a258a0e5313f0f55c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 16:25:47 -0500 Subject: [PATCH 100/229] Fix terrafmt errors in acceptance test configurations. --- internal/service/networkmanager/site_data_source_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/networkmanager/site_data_source_test.go b/internal/service/networkmanager/site_data_source_test.go index cbcc25aa5ba..86e958fceaf 100644 --- a/internal/service/networkmanager/site_data_source_test.go +++ b/internal/service/networkmanager/site_data_source_test.go @@ -48,7 +48,7 @@ resource "aws_networkmanager_site" "test" { global_network_id = aws_networkmanager_global_network.test.id location { - latitude = "18.0029784" + latitude = "18.0029784" longitude = "-76.7897987" } From f1c4ec972b8ccaad259aac3ae4e5b1a213d9755f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 17:08:47 -0500 Subject: [PATCH 101/229] Fix 'misspell' golangci-lint error. --- internal/service/networkmanager/device_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/networkmanager/device_test.go b/internal/service/networkmanager/device_test.go index dacde8cbb84..e0f867d668e 100644 --- a/internal/service/networkmanager/device_test.go +++ b/internal/service/networkmanager/device_test.go @@ -51,7 +51,7 @@ func TestAccNetworkManagerDevice_basic(t *testing.T) { }) } -func TestAccNetworkManagerDevice_disapears(t *testing.T) { +func TestAccNetworkManagerDevice_disappears(t *testing.T) { resourceName := "aws_networkmanager_device.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) From 509d45b0e4a47b15f291905073fc1796c70c048f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 4 Mar 2022 17:10:08 -0500 Subject: [PATCH 102/229] Fix 'A name must start with a letter or underscore and may contain only letters, digits, underscores, and dashes.'. --- website/docs/d/networkmanager_site.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/d/networkmanager_site.html.markdown b/website/docs/d/networkmanager_site.html.markdown index fdead78104c..51bb1f03faf 100644 --- a/website/docs/d/networkmanager_site.html.markdown +++ b/website/docs/d/networkmanager_site.html.markdown @@ -13,7 +13,7 @@ Retrieve information about a site. ## Example Usage ```terraform -data " aws_networkmanager_site" "example" { +data "aws_networkmanager_site" "example" { global_network_id = var.global_network_id site_id = var.site_id } From cfc4fd4b55a04054d328c1d6ab70039a580778b3 Mon Sep 17 00:00:00 2001 From: Paul Rutledge Date: Sun, 6 Mar 2022 10:57:00 -0600 Subject: [PATCH 103/229] add aws_ecrpublic_authorization_token data source --- internal/provider/provider.go | 2 + .../authorization_token_data_source.go | 72 +++++++++++++++++++ .../authorization_token_data_source_test.go | 36 ++++++++++ ...crpublic_authorization_token.html.markdown | 28 ++++++++ 4 files changed, 138 insertions(+) create mode 100644 internal/service/ecrpublic/authorization_token_data_source.go create mode 100644 internal/service/ecrpublic/authorization_token_data_source_test.go create mode 100644 website/docs/d/ecrpublic_authorization_token.html.markdown diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 740144a03e3..dfde1e3acff 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -580,6 +580,8 @@ func Provider() *schema.Provider { "aws_ecr_image": ecr.DataSourceImage(), "aws_ecr_repository": ecr.DataSourceRepository(), + "aws_ecrpublic_authorization_token": ecrpublic.DataSourceAuthorizationToken(), + "aws_ecs_cluster": ecs.DataSourceCluster(), "aws_ecs_container_definition": ecs.DataSourceContainerDefinition(), "aws_ecs_service": ecs.DataSourceService(), diff --git a/internal/service/ecrpublic/authorization_token_data_source.go b/internal/service/ecrpublic/authorization_token_data_source.go new file mode 100644 index 00000000000..cfd310a81a9 --- /dev/null +++ b/internal/service/ecrpublic/authorization_token_data_source.go @@ -0,0 +1,72 @@ +package ecrpublic + +import ( + "encoding/base64" + "fmt" + "log" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ecrpublic" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" +) + +func DataSourceAuthorizationToken() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAuthorizationTokenRead, + + Schema: map[string]*schema.Schema{ + "authorization_token": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + "expires_at": { + Type: schema.TypeString, + Computed: true, + }, + "user_name": { + Type: schema.TypeString, + Computed: true, + }, + "password": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + }, + } +} + +func dataSourceAuthorizationTokenRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).ECRPublicConn + params := &ecrpublic.GetAuthorizationTokenInput{} + log.Printf("[DEBUG] Getting Public ECR authorization token") + out, err := conn.GetAuthorizationToken(params) + if err != nil { + return fmt.Errorf("error getting Public ECR authorization token: %w", err) + } + log.Printf("[DEBUG] Received Public ECR AuthorizationData %v", out.AuthorizationData) + authorizationData := out.AuthorizationData + authorizationToken := aws.StringValue(authorizationData.AuthorizationToken) + expiresAt := aws.TimeValue(authorizationData.ExpiresAt).Format(time.RFC3339) + authBytes, err := base64.URLEncoding.DecodeString(authorizationToken) + if err != nil { + d.SetId("") + return fmt.Errorf("error decoding Public ECR authorization token: %w", err) + } + basicAuthorization := strings.Split(string(authBytes), ":") + if len(basicAuthorization) != 2 { + return fmt.Errorf("unknown Public ECR authorization token format") + } + userName := basicAuthorization[0] + password := basicAuthorization[1] + d.SetId(meta.(*conns.AWSClient).Region) + d.Set("authorization_token", authorizationToken) + d.Set("expires_at", expiresAt) + d.Set("user_name", userName) + d.Set("password", password) + return nil +} diff --git a/internal/service/ecrpublic/authorization_token_data_source_test.go b/internal/service/ecrpublic/authorization_token_data_source_test.go new file mode 100644 index 00000000000..444fe31ef08 --- /dev/null +++ b/internal/service/ecrpublic/authorization_token_data_source_test.go @@ -0,0 +1,36 @@ +package ecrpublic_test + +import ( + "regexp" + "testing" + + "github.com/aws/aws-sdk-go/service/ecr" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" +) + +func TestAccECRPublicAuthorizationTokenDataSource_basic(t *testing.T) { + dataSourceName := "data.aws_ecrpublic_authorization_token.repo" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, ecr.EndpointsID), + Providers: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccCheckAuthorizationTokenBasicDataSourceConfig, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(dataSourceName, "authorization_token"), + resource.TestCheckResourceAttrSet(dataSourceName, "expires_at"), + resource.TestCheckResourceAttrSet(dataSourceName, "user_name"), + resource.TestMatchResourceAttr(dataSourceName, "user_name", regexp.MustCompile(`AWS`)), + resource.TestCheckResourceAttrSet(dataSourceName, "password"), + ), + }, + }, + }) +} + +var testAccCheckAuthorizationTokenBasicDataSourceConfig = ` +data "aws_ecrpublic_authorization_token" "repo" {} +` diff --git a/website/docs/d/ecrpublic_authorization_token.html.markdown b/website/docs/d/ecrpublic_authorization_token.html.markdown new file mode 100644 index 00000000000..755fc5d71ec --- /dev/null +++ b/website/docs/d/ecrpublic_authorization_token.html.markdown @@ -0,0 +1,28 @@ +--- +subcategory: "ECR" +layout: "aws" +page_title: "AWS: aws_ecrpublic_authorization_token" +description: |- + Provides details about a Public ECR Authorization Token +--- + +# Data Source: aws_ecrpublic_authorization_token + +The Public ECR Authorization Token data source allows the authorization token, token expiration date, user name and password to be retrieved for a Public ECR repository. + +## Example Usage + +```terraform +data "aws_ecrpublic_authorization_token" "token" { +} +``` + +## Attributes Reference + +The following attributes are exported: + +* `authorization_token` - Temporary IAM authentication credentials to access the ECR repository encoded in base64 in the form of `user_name:password`. +* `expires_at` - The time in UTC RFC3339 format when the authorization token expires. +* `id` - Region of the authorization token. +* `password` - Password decoded from the authorization token. +* `user_name` - User name decoded from the authorization token. From 87d7106434c655234f9a047c9a15303c3e68934f Mon Sep 17 00:00:00 2001 From: Andrew Johnston Date: Wed, 9 Mar 2022 20:08:40 -0500 Subject: [PATCH 104/229] r/aws_gamelift_game_server_group --- internal/provider/provider.go | 1 + internal/service/gamelift/find.go | 25 + .../service/gamelift/game_server_group.go | 588 +++++++++ .../gamelift/game_server_group_test.go | 1072 +++++++++++++++++ internal/service/gamelift/status.go | 16 + internal/service/gamelift/wait.go | 45 + 6 files changed, 1747 insertions(+) create mode 100644 internal/service/gamelift/game_server_group.go create mode 100644 internal/service/gamelift/game_server_group_test.go diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 740144a03e3..9d94cd10cb1 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1390,6 +1390,7 @@ func Provider() *schema.Provider { "aws_gamelift_alias": gamelift.ResourceAlias(), "aws_gamelift_build": gamelift.ResourceBuild(), "aws_gamelift_fleet": gamelift.ResourceFleet(), + "aws_gamelift_game_server_group": gamelift.ResourceGameServerGroup(), "aws_gamelift_game_session_queue": gamelift.ResourceGameSessionQueue(), "aws_gamelift_script": gamelift.ResourceScript(), diff --git a/internal/service/gamelift/find.go b/internal/service/gamelift/find.go index 7adf6b37fc2..05acc1d2524 100644 --- a/internal/service/gamelift/find.go +++ b/internal/service/gamelift/find.go @@ -68,6 +68,31 @@ func FindFleetByID(conn *gamelift.GameLift, id string) (*gamelift.FleetAttribute return fleet, nil } +func FindGameServerGroupByName(conn *gamelift.GameLift, name string) (*gamelift.GameServerGroup, error) { + input := &gamelift.DescribeGameServerGroupInput{ + GameServerGroupName: aws.String(name), + } + + output, err := conn.DescribeGameServerGroup(input) + + if tfawserr.ErrCodeEquals(err, gamelift.ErrCodeNotFoundException) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + if output == nil || output.GameServerGroup == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + return output.GameServerGroup, nil +} + func FindScriptByID(conn *gamelift.GameLift, id string) (*gamelift.Script, error) { input := &gamelift.DescribeScriptInput{ ScriptId: aws.String(id), diff --git a/internal/service/gamelift/game_server_group.go b/internal/service/gamelift/game_server_group.go new file mode 100644 index 00000000000..81edbf9308f --- /dev/null +++ b/internal/service/gamelift/game_server_group.go @@ -0,0 +1,588 @@ +package gamelift + +import ( + "fmt" + "log" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/autoscaling" + "github.com/aws/aws-sdk-go/service/gamelift" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/flex" + tfiam "github.com/hashicorp/terraform-provider-aws/internal/service/iam" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/internal/verify" +) + +const ( + gameServerGroupCreatedDefaultTimeout = 10 * time.Minute + gameServerGroupDeletedDefaultTimeout = 30 * time.Minute +) + +func ResourceGameServerGroup() *schema.Resource { + return &schema.Resource{ + Create: resourceGameServerGroupCreate, + Read: resourceGameServerGroupRead, + Update: resourceGameServerGroupUpdate, + Delete: resourceGameServerGroupDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(gameServerGroupCreatedDefaultTimeout), + Delete: schema.DefaultTimeout(gameServerGroupDeletedDefaultTimeout), + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "auto_scaling_group_arn": { + Type: schema.TypeString, + Computed: true, + }, + "auto_scaling_policy": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "estimated_instance_warmup": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validation.IntAtLeast(1), + }, + "target_tracking_configuration": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "target_value": { + Type: schema.TypeFloat, + Required: true, + ForceNew: true, + ValidateFunc: validation.FloatAtLeast(0), + }, + }, + }, + }, + }, + }, + }, + "balancing_strategy": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice(gamelift.BalancingStrategy_Values(), false), + }, + "game_server_group_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 128), + }, + "game_server_protection_policy": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice(gamelift.GameServerProtectionPolicy_Values(), false), + }, + "instance_definition": { + Type: schema.TypeSet, + Required: true, + MinItems: 2, + MaxItems: 20, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "instance_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(gamelift.GameServerGroupInstanceType_Values(), false), + }, + "weighted_capacity": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(1, 3), + }, + }, + }, + }, + "launch_template": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"launch_template.0.name"}, + ValidateFunc: verify.ValidLaunchTemplateID, + }, + "name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"launch_template.0.id"}, + ValidateFunc: verify.ValidLaunchTemplateName, + }, + "version": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 128), + }, + }, + }, + }, + "max_size": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + ValidateFunc: validation.IntAtLeast(1), + }, + "min_size": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + ValidateFunc: validation.IntAtLeast(0), + }, + "role_arn": { + Type: schema.TypeString, + Required: true, + ValidateFunc: verify.ValidARN, + }, + "tags": tftags.TagsSchema(), + "tags_all": tftags.TagsSchemaComputed(), + "vpc_subnets": { + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + MaxItems: 20, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringLenBetween(15, 24), + }, + }, + }, + } +} + +func resourceGameServerGroupCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).GameLiftConn + defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{}))) + + input := &gamelift.CreateGameServerGroupInput{ + GameServerGroupName: aws.String(d.Get("game_server_group_name").(string)), + InstanceDefinitions: expandGameliftInstanceDefinitions(d.Get("instance_definition").(*schema.Set).List()), + LaunchTemplate: expandGameliftLaunchTemplateSpecification(d.Get("launch_template").([]interface{})[0].(map[string]interface{})), + MaxSize: aws.Int64(int64(d.Get("max_size").(int))), + MinSize: aws.Int64(int64(d.Get("min_size").(int))), + RoleArn: aws.String(d.Get("role_arn").(string)), + Tags: Tags(tags.IgnoreAWS()), + } + + if v, ok := d.GetOk("auto_scaling_policy"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.AutoScalingPolicy = expandGameliftGameServerGroupAutoScalingPolicy(v.([]interface{})[0].(map[string]interface{})) + } + + if v, ok := d.GetOk("balancing_strategy"); ok { + input.BalancingStrategy = aws.String(v.(string)) + } + + if v, ok := d.GetOk("game_server_protection_policy"); ok { + input.GameServerProtectionPolicy = aws.String(v.(string)) + } + + if v, ok := d.GetOk("vpc_subnets"); ok && v.(*schema.Set).Len() > 0 { + input.VpcSubnets = flex.ExpandStringSet(v.(*schema.Set)) + } + + log.Printf("[INFO] Creating Gamelift Game Server Group: %s", input) + var out *gamelift.CreateGameServerGroupOutput + err := resource.Retry(tfiam.PropagationTimeout, func() *resource.RetryError { + var err error + out, err = conn.CreateGameServerGroup(input) + + if tfawserr.ErrMessageContains(err, gamelift.ErrCodeInvalidRequestException, "GameLift is not authorized to perform") { + return resource.RetryableError(err) + } + + if err != nil { + return resource.NonRetryableError(err) + } + + return nil + }) + + if tfresource.TimedOut(err) { + out, err = conn.CreateGameServerGroup(input) + } + + if err != nil { + return fmt.Errorf("error creating GameLift Game Server Group (%s): %w", d.Get("name").(string), err) + } + + d.SetId(aws.StringValue(out.GameServerGroup.GameServerGroupName)) + + if output, err := waitGameServerGroupActive(conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { + return fmt.Errorf("error waiting for GameLift Game Server Group (%s) to become active (%s): %w", d.Id(), *output.StatusReason, err) + } + + return resourceGameServerGroupRead(d, meta) +} + +func resourceGameServerGroupRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).GameLiftConn + autoscalingConn := meta.(*conns.AWSClient).AutoScalingConn + defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig + + gameServerGroupName := d.Id() + + log.Printf("[INFO] Describing Gamelift Game Server Group: %s", gameServerGroupName) + gameServerGroup, err := FindGameServerGroupByName(conn, gameServerGroupName) + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] GameLift Game Server Group (%s) not found, removing from state", gameServerGroupName) + d.SetId("") + return nil + } + + if err != nil { + return fmt.Errorf("error reading GameLift Game Server Group (%s): %w", gameServerGroupName, err) + } + + autoScalingGroupName := strings.Split(aws.StringValue(gameServerGroup.AutoScalingGroupArn), "/")[1] + autoScalingGroupOutput, err := autoscalingConn.DescribeAutoScalingGroups(&autoscaling.DescribeAutoScalingGroupsInput{ + AutoScalingGroupNames: []*string{aws.String(autoScalingGroupName)}, + }) + if err != nil { + return err + } + if autoScalingGroupOutput == nil || len(autoScalingGroupOutput.AutoScalingGroups) == 0 { + return fmt.Errorf("error describing Auto Scaling Group (%s): not found", autoScalingGroupName) + } + autoScalingGroup := autoScalingGroupOutput.AutoScalingGroups[0] + + describePoliciesOutput, err := autoscalingConn.DescribePolicies(&autoscaling.DescribePoliciesInput{ + AutoScalingGroupName: aws.String(autoScalingGroupName), + PolicyNames: []*string{aws.String(gameServerGroupName)}, + }) + + if err != nil { + return fmt.Errorf("error describing Auto Scaling Group Policies (%s): %s", autoScalingGroupName, err) + } + + arn := aws.StringValue(gameServerGroup.GameServerGroupArn) + d.Set("arn", arn) + d.Set("auto_scaling_group_arn", gameServerGroup.AutoScalingGroupArn) + d.Set("balancing_strategy", gameServerGroup.BalancingStrategy) + d.Set("game_server_group_name", gameServerGroupName) + d.Set("game_server_protection_policy", gameServerGroup.GameServerProtectionPolicy) + d.Set("max_size", autoScalingGroup.MaxSize) + d.Set("min_size", autoScalingGroup.MinSize) + d.Set("role_arn", gameServerGroup.RoleArn) + + if len(describePoliciesOutput.ScalingPolicies) == 1 { + if err := d.Set("auto_scaling_policy", []interface{}{flattenGameliftGameServerGroupAutoScalingPolicy(describePoliciesOutput.ScalingPolicies[0])}); err != nil { + return fmt.Errorf("error setting auto_scaling_policy: %w", err) + } + } else { + d.Set("auto_scaling_policy", nil) + } + + if err := d.Set("instance_definition", flattenGameliftInstanceDefinitions(gameServerGroup.InstanceDefinitions)); err != nil { + return fmt.Errorf("error setting instance_definition: %s", err) + } + + if err := d.Set("launch_template", flattenAutoscalingLaunchTemplateSpecification(autoScalingGroup.MixedInstancesPolicy.LaunchTemplate.LaunchTemplateSpecification)); err != nil { + return fmt.Errorf("error setting launch_template: %s", err) + } + + tags, err := ListTags(conn, arn) + + if tfawserr.ErrMessageContains(err, gamelift.ErrCodeInvalidRequestException, fmt.Sprintf("Resource %s is not in a taggable state", d.Id())) { + return nil + } + + if err != nil { + return fmt.Errorf("error listing tags for Game Lift Game Server Group (%s): %s", arn, err) + } + + tags = tags.IgnoreAWS().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) + } + + return nil +} + +func resourceGameServerGroupUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).GameLiftConn + + log.Printf("[INFO] Updating Gamelift Game Server Group: %s", d.Id()) + + if d.HasChanges("balancing_strategy", "game_server_protection_policy", "instance_definition", "role_arn") { + input := gamelift.UpdateGameServerGroupInput{ + GameServerGroupName: aws.String(d.Id()), + InstanceDefinitions: expandGameliftInstanceDefinitions(d.Get("instance_definition").(*schema.Set).List()), + RoleArn: aws.String(d.Get("role_arn").(string)), + } + + if v, ok := d.GetOk("balancing_strategy"); ok { + input.BalancingStrategy = aws.String(v.(string)) + } + + if v, ok := d.GetOk("game_server_protection_policy"); ok { + input.GameServerProtectionPolicy = aws.String(v.(string)) + } + + _, err := conn.UpdateGameServerGroup(&input) + if err != nil { + return fmt.Errorf("error updating GameLift Game Server Group (%s): %w", d.Id(), err) + } + } + + if d.HasChange("tags_all") { + arn := d.Get("arn").(string) + o, n := d.GetChange("tags_all") + + if err := UpdateTags(conn, arn, o, n); err != nil { + return fmt.Errorf("error updating Game Lift Game Server Group (%s) tags: %w", arn, err) + } + } + + return resourceGameServerGroupRead(d, meta) +} + +func resourceGameServerGroupDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).GameLiftConn + + log.Printf("[INFO] Deleting Gamelift Game Server Group: %s", d.Id()) + input := &gamelift.DeleteGameServerGroupInput{ + GameServerGroupName: aws.String(d.Id()), + } + err := resource.Retry(gameServerGroupDeletedDefaultTimeout, func() *resource.RetryError { + _, err := conn.DeleteGameServerGroup(input) + if err != nil { + msg := fmt.Sprintf("Cannot delete game server group %s: %s", d.Id(), err) + if tfawserr.ErrMessageContains(err, gamelift.ErrCodeInvalidRequestException, msg) { + return resource.RetryableError(err) + } + return resource.NonRetryableError(err) + } + return nil + }) + if tfresource.TimedOut(err) { + _, err = conn.DeleteGameServerGroup(input) + } + if err != nil { + if tfawserr.ErrCodeEquals(err, gamelift.ErrCodeNotFoundException) { + return nil + } + return fmt.Errorf("Error deleting Gamelift game server group: %w", err) + } + + if err := waitGameServerGroupTerminated(conn, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil { + return fmt.Errorf("error waiting for GameLift Game Server Group (%s) to be deleted: %w", d.Id(), err) + } + + return nil +} + +func expandGameliftGameServerGroupAutoScalingPolicy(tfMap map[string]interface{}) *gamelift.GameServerGroupAutoScalingPolicy { + if tfMap == nil { + return nil + } + + apiObject := &gamelift.GameServerGroupAutoScalingPolicy{ + TargetTrackingConfiguration: expandGameliftTargetTrackingConfiguration(tfMap["target_tracking_configuration"].([]interface{})[0].(map[string]interface{})), + } + + if v, ok := tfMap["estimated_instance_warmup"].(int); ok && v != 0 { + apiObject.EstimatedInstanceWarmup = aws.Int64(int64(v)) + } + + return apiObject +} + +func expandGameliftInstanceDefinition(tfMap map[string]interface{}) *gamelift.InstanceDefinition { + if tfMap == nil { + return nil + } + + apiObject := &gamelift.InstanceDefinition{ + InstanceType: aws.String(tfMap["instance_type"].(string)), + } + + if v, ok := tfMap["weighted_capacity"].(string); ok && v != "" { + apiObject.WeightedCapacity = aws.String(v) + } + + return apiObject +} + +func expandGameliftInstanceDefinitions(tfList []interface{}) []*gamelift.InstanceDefinition { + if len(tfList) == 0 { + return nil + } + + var apiObjects []*gamelift.InstanceDefinition + + for _, tfMapRaw := range tfList { + tfMap, ok := tfMapRaw.(map[string]interface{}) + + if !ok { + continue + } + + apiObject := expandGameliftInstanceDefinition(tfMap) + + if apiObject == nil { + continue + } + + apiObjects = append(apiObjects, apiObject) + } + + return apiObjects +} + +func expandGameliftLaunchTemplateSpecification(tfMap map[string]interface{}) *gamelift.LaunchTemplateSpecification { + if tfMap == nil { + return nil + } + + apiObject := &gamelift.LaunchTemplateSpecification{} + + if v, ok := tfMap["id"].(string); ok && v != "" { + apiObject.LaunchTemplateId = aws.String(v) + } + + if v, ok := tfMap["name"].(string); ok && v != "" { + apiObject.LaunchTemplateName = aws.String(v) + } + + if v, ok := tfMap["version"].(string); ok && v != "" { + apiObject.Version = aws.String(v) + } + + return apiObject +} + +func expandGameliftTargetTrackingConfiguration(tfMap map[string]interface{}) *gamelift.TargetTrackingConfiguration { + if tfMap == nil { + return nil + } + + apiObject := &gamelift.TargetTrackingConfiguration{ + TargetValue: aws.Float64(tfMap["target_value"].(float64)), + } + + return apiObject +} + +func flattenGameliftGameServerGroupAutoScalingPolicy(apiObject *autoscaling.ScalingPolicy) map[string]interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{ + "target_tracking_configuration": []interface{}{flattenGameliftTargetTrackingConfiguration(apiObject.TargetTrackingConfiguration)}, + } + + if v := apiObject.EstimatedInstanceWarmup; v != nil { + tfMap["estimated_instance_warmup"] = aws.Int64Value(v) + } + + return tfMap +} + +func flattenGameliftInstanceDefinition(apiObject *gamelift.InstanceDefinition) map[string]interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{ + "instance_type": aws.StringValue(apiObject.InstanceType), + } + + if v := apiObject.WeightedCapacity; v != nil { + tfMap["weighted_capacity"] = aws.StringValue(v) + } + + return tfMap +} + +func flattenAutoscalingLaunchTemplateSpecification(apiObject *autoscaling.LaunchTemplateSpecification) []map[string]interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{ + "id": aws.StringValue(apiObject.LaunchTemplateId), + "name": aws.StringValue(apiObject.LaunchTemplateName), + } + + // version is returned only if it was previously set + if apiObject.Version != nil { + tfMap["version"] = aws.StringValue(apiObject.Version) + } else { + tfMap["version"] = nil + } + + return []map[string]interface{}{tfMap} +} + +func flattenGameliftInstanceDefinitions(apiObjects []*gamelift.InstanceDefinition) []interface{} { + if len(apiObjects) == 0 { + return nil + } + + var tfList []interface{} + + for _, apiObject := range apiObjects { + if apiObject == nil { + continue + } + + tfList = append(tfList, flattenGameliftInstanceDefinition(apiObject)) + } + + return tfList +} + +func flattenGameliftTargetTrackingConfiguration(apiObject *autoscaling.TargetTrackingConfiguration) map[string]interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{ + "target_value": aws.Float64Value(apiObject.TargetValue), + } + + return tfMap +} diff --git a/internal/service/gamelift/game_server_group_test.go b/internal/service/gamelift/game_server_group_test.go new file mode 100644 index 00000000000..4d033eec97d --- /dev/null +++ b/internal/service/gamelift/game_server_group_test.go @@ -0,0 +1,1072 @@ +package gamelift_test + +import ( + "fmt" + "regexp" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/gamelift" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + 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" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" +) + +func TestAccGameliftGameServerGroup_basic(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) + testAccPreCheck(t) + }, + ErrorCheck: acctest.ErrorCheck(t, gamelift.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "gamelift", regexp.MustCompile(`gameservergroup/.+`)), + acctest.MatchResourceAttrRegionalARN(resourceName, "auto_scaling_group_arn", "autoscaling", regexp.MustCompile(`autoScalingGroup:.+`)), + resource.TestCheckResourceAttr(resourceName, "auto_scaling_policy.#", "0"), + resource.TestCheckResourceAttr(resourceName, "balancing_strategy", gamelift.BalancingStrategySpotPreferred), + resource.TestCheckResourceAttr(resourceName, "game_server_protection_policy", gamelift.GameServerProtectionPolicyNoProtection), + resource.TestCheckResourceAttr(resourceName, "launch_template.0.version", ""), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_AutoScalingPolicy(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) + testAccPreCheck(t) + }, + Providers: acctest.Providers, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigAutoScalingPolicy(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auto_scaling_policy.0.estimated_instance_warmup", "60"), + resource.TestCheckResourceAttr(resourceName, "auto_scaling_policy.0.target_tracking_configuration.0.target_value", "77.7"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_AutoScalingPolicy_EstimatedInstanceWarmup(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) + testAccPreCheck(t) + }, + Providers: acctest.Providers, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigAutoScalingPolicyEstimatedInstanceWarmup(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "auto_scaling_policy.0.estimated_instance_warmup", "66"), + resource.TestCheckResourceAttr(resourceName, "auto_scaling_policy.0.target_tracking_configuration.0.target_value", "77.7"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_BalancingStrategy(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) + testAccPreCheck(t) + }, + Providers: acctest.Providers, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigBalancingStrategy(rName, gamelift.BalancingStrategySpotOnly), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "balancing_strategy", gamelift.BalancingStrategySpotOnly), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_GameServerGroupName(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) + testAccPreCheck(t) + }, + Providers: acctest.Providers, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigGameServerGroupName(rName, rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "game_server_group_name", rName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGameliftGameServerGroupConfigGameServerGroupName(rName, rName+"-new"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "game_server_group_name", rName+"-new"), + ), + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_InstanceDefinition(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) + testAccPreCheck(t) + }, + Providers: acctest.Providers, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigInstanceDefinition(rName, 2), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "instance_definition.#", "2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGameliftGameServerGroupConfigInstanceDefinition(rName, 3), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "instance_definition.#", "3"), + ), + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_InstanceDefinition_WeightedCapacity(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) + testAccPreCheck(t) + }, + Providers: acctest.Providers, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigInstanceDefinitionWeightedCapacity(rName, "1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "instance_definition.#", "2"), + resource.TestCheckResourceAttr(resourceName, "instance_definition.0.weighted_capacity", "1"), + resource.TestCheckResourceAttr(resourceName, "instance_definition.1.weighted_capacity", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGameliftGameServerGroupConfigInstanceDefinitionWeightedCapacity(rName, "2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "instance_definition.#", "2"), + resource.TestCheckResourceAttr(resourceName, "instance_definition.0.weighted_capacity", "2"), + resource.TestCheckResourceAttr(resourceName, "instance_definition.1.weighted_capacity", "2"), + ), + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_LaunchTemplate_Id(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) + testAccPreCheck(t) + }, + Providers: acctest.Providers, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigLaunchTemplateId(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "launch_template.0.id", "aws_launch_template.test", "id"), + resource.TestCheckResourceAttr(resourceName, "launch_template.0.name", rName), + resource.TestCheckResourceAttr(resourceName, "launch_template.0.version", ""), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_LaunchTemplate_Name(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) + testAccPreCheck(t) + }, + Providers: acctest.Providers, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigLaunchTemplateName(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "launch_template.0.id", "aws_launch_template.test", "id"), + resource.TestCheckResourceAttr(resourceName, "launch_template.0.name", rName), + resource.TestCheckResourceAttr(resourceName, "launch_template.0.version", ""), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_LaunchTemplate_Version(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) + testAccPreCheck(t) + }, + Providers: acctest.Providers, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigLaunchTemplateVersion(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "launch_template.0.id", "aws_launch_template.test", "id"), + resource.TestCheckResourceAttr(resourceName, "launch_template.0.name", rName), + resource.TestCheckResourceAttr(resourceName, "launch_template.0.version", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_GameServerProtectionPolicy(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) + testAccPreCheck(t) + }, + Providers: acctest.Providers, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigGameServerProtectionPolicy(rName, gamelift.GameServerProtectionPolicyFullProtection), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "game_server_protection_policy", gamelift.GameServerProtectionPolicyFullProtection), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_MaxSize(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) + testAccPreCheck(t) + }, + Providers: acctest.Providers, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigMaxSize(rName, "1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "max_size", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGameliftGameServerGroupConfigMaxSize(rName, "2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "max_size", "2"), + ), + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_MinSize(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) + testAccPreCheck(t) + }, + Providers: acctest.Providers, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigMinSize(rName, "1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "min_size", "1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGameliftGameServerGroupConfigMinSize(rName, "2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "min_size", "2"), + ), + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_RoleArn(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) + testAccPreCheck(t) + }, + Providers: acctest.Providers, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigRoleArn(rName, "test1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + acctest.CheckResourceAttrGlobalARN(resourceName, "role_arn", "iam", fmt.Sprintf(`role/%s-test1`, rName)), + resource.TestCheckResourceAttrPair(resourceName, "role_arn", "aws_iam_role.test1", "arn"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccGameliftGameServerGroupConfigRoleArn(rName, "test2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + acctest.CheckResourceAttrGlobalARN(resourceName, "role_arn", "iam", fmt.Sprintf(`role/%s-test2`, rName)), + resource.TestCheckResourceAttrPair(resourceName, "role_arn", "aws_iam_role.test2", "arn"), + ), + }, + }, + }) +} + +func TestAccGameliftGameServerGroup_VpcSubnets(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_gamelift_game_server_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) + testAccPreCheck(t) + }, + Providers: acctest.Providers, + CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGameliftGameServerGroupConfigVpcSubnets(rName, 1), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"vpc_subnets"}, + }, + { + Config: testAccGameliftGameServerGroupConfigVpcSubnets(rName, 2), + Check: resource.ComposeTestCheckFunc( + testAccCheckGameliftGameServerGroupExists(resourceName), + ), + }, + }, + }) +} + +func testAccCheckGameliftGameServerGroupDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).GameLiftConn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_gamelift_game_server_group" { + continue + } + + input := gamelift.DescribeGameServerGroupInput{ + GameServerGroupName: aws.String(rs.Primary.ID), + } + + output, err := conn.DescribeGameServerGroup(&input) + + if tfawserr.ErrCodeEquals(err, gamelift.ErrCodeNotFoundException) { + continue + } + + if err != nil { + return err + } + + if output != nil { + return fmt.Errorf("Gamelift Game Server Group (%s) still exists", rs.Primary.ID) + } + } + + return nil +} + +func testAccCheckGameliftGameServerGroupExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("resource %s not found", resourceName) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("resource %s has not set its id", resourceName) + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).GameLiftConn + + input := gamelift.DescribeGameServerGroupInput{ + GameServerGroupName: aws.String(rs.Primary.ID), + } + + output, err := conn.DescribeGameServerGroup(&input) + + if err != nil { + return fmt.Errorf("error reading Gamelift Game Server Group (%s): %w", rs.Primary.ID, err) + } + + if output == nil { + return fmt.Errorf("Gamelift Game Server Group (%s) not found", rs.Primary.ID) + } + + return nil + } +} + +func testAccGameliftGameServerGroupIamConfig(rName string, name string) string { + return fmt.Sprintf(` +data "aws_partition" %[2]q {} +resource "aws_iam_role" %[2]q { + assume_role_policy = <<-EOF + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": [ + "autoscaling.amazonaws.com", + "gamelift.amazonaws.com" + ] + }, + "Action": "sts:AssumeRole" + } + ] + } + EOF + name = "%[1]s-%[2]s" +} +resource "aws_iam_role_policy_attachment" %[2]q { + policy_arn = "arn:${data.aws_partition.%[2]s.partition}:iam::aws:policy/GameLiftGameServerGroupPolicy" + role = aws_iam_role.%[2]s.name +} +`, rName, name) +} + +func testAccGameliftGameServerGroupLaunchTemplateConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_launch_template" "test" { + image_id = data.aws_ami.amzn-ami-minimal-hvm-ebs.id + name = %[1]q +} +`, rName) +} + +func testAccGameliftGameServerGroupInstanceTypeOfferingsConfig() string { + return ` +data "aws_ec2_instance_type_offerings" "available" { + filter { + name = "instance-type" + values = ["c5a.large", "c5a.2xlarge", "c5.large", "c5.2xlarge", "m4.large", "m4.2xlarge", "m5a.large", "m5a.2xlarge", "m5.large", "m5.2xlarge"] + } +} +` +} + +func testAccGameliftGameServerGroupConfig(rName string) string { + return acctest.ConfigCompose( + acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + content { + instance_type = instance_definition.value + } + } + launch_template { + id = aws_launch_template.test.id + } + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName)) +} + +func testAccGameliftGameServerGroupConfigAutoScalingPolicy(rName string) string { + return acctest.ConfigCompose( + acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + auto_scaling_policy { + target_tracking_configuration { + target_value = 77.7 + } + } + game_server_group_name = %[1]q + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + content { + instance_type = instance_definition.value + } + } + launch_template { + id = aws_launch_template.test.id + } + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName)) +} + +func testAccGameliftGameServerGroupConfigAutoScalingPolicyEstimatedInstanceWarmup(rName string) string { + return acctest.ConfigCompose( + acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + auto_scaling_policy { + estimated_instance_warmup = 66 + target_tracking_configuration { + target_value = 77.7 + } + } + game_server_group_name = %[1]q + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + content { + instance_type = instance_definition.value + } + } + launch_template { + id = aws_launch_template.test.id + } + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName)) +} + +func testAccGameliftGameServerGroupConfigBalancingStrategy(rName string, balancingStrategy string) string { + return acctest.ConfigCompose( + acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + balancing_strategy = %[2]q + game_server_group_name = %[1]q + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + content { + instance_type = instance_definition.value + } + } + launch_template { + id = aws_launch_template.test.id + } + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName, balancingStrategy)) +} + +func testAccGameliftGameServerGroupConfigGameServerGroupName(rName string, gameServerGroupName string) string { + return acctest.ConfigCompose( + acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + content { + instance_type = instance_definition.value + } + } + launch_template { + id = aws_launch_template.test.id + } + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] +} +`, gameServerGroupName)) +} + +func testAccGameliftGameServerGroupConfigInstanceDefinition(rName string, count int) string { + return acctest.ConfigCompose( + acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + dynamic "instance_definition" { + for_each = slice(sort(tolist(data.aws_ec2_instance_type_offerings.available.instance_types)), 0, %[2]d) + content { + instance_type = instance_definition.value + } + } + launch_template { + id = aws_launch_template.test.id + } + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName, count)) +} + +func testAccGameliftGameServerGroupConfigInstanceDefinitionWeightedCapacity(rName string, weightedCapacity string) string { + return acctest.ConfigCompose( + acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + dynamic "instance_definition" { + for_each = slice(sort(tolist(data.aws_ec2_instance_type_offerings.available.instance_types)), 0, 2) + content { + instance_type = instance_definition.value + weighted_capacity = %[2]q + } + } + launch_template { + id = aws_launch_template.test.id + } + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName, weightedCapacity)) +} + +func testAccGameliftGameServerGroupConfigLaunchTemplateId(rName string) string { + return acctest.ConfigCompose( + acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + content { + instance_type = instance_definition.value + } + } + launch_template { + id = aws_launch_template.test.id + } + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName)) +} + +func testAccGameliftGameServerGroupConfigLaunchTemplateName(rName string) string { + return acctest.ConfigCompose( + acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + content { + instance_type = instance_definition.value + } + } + launch_template { + name = aws_launch_template.test.name + } + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName)) +} + +func testAccGameliftGameServerGroupConfigLaunchTemplateVersion(rName string) string { + return acctest.ConfigCompose( + acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + content { + instance_type = instance_definition.value + } + } + launch_template { + id = aws_launch_template.test.id + version = 1 + } + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName)) +} + +func testAccGameliftGameServerGroupConfigMaxSize(rName string, maxSize string) string { + return acctest.ConfigCompose( + acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + content { + instance_type = instance_definition.value + } + } + launch_template { + id = aws_launch_template.test.id + } + max_size = %[2]s + min_size = 1 + role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName, maxSize)) +} + +func testAccGameliftGameServerGroupConfigMinSize(rName string, minSize string) string { + return acctest.ConfigCompose( + acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + content { + instance_type = instance_definition.value + } + } + launch_template { + id = aws_launch_template.test.id + } + max_size = 2 + min_size = %[2]s + role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName, minSize)) +} + +func testAccGameliftGameServerGroupConfigTags(rName string, key string, value string) string { + return acctest.ConfigCompose( + acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + content { + instance_type = instance_definition.value + } + } + launch_template { + id = aws_launch_template.test.id + } + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + tags = { + %[2]s = %[3]q + } + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName, key, value)) +} + +func testAccGameliftGameServerGroupConfigGameServerProtectionPolicy(rName string, gameServerProtectionPolicy string) string { + return acctest.ConfigCompose( + acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + game_server_protection_policy = %[2]q + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + content { + instance_type = instance_definition.value + } + } + launch_template { + id = aws_launch_template.test.id + } + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName, gameServerProtectionPolicy)) +} + +func testAccGameliftGameServerGroupConfigRoleArn(rName string, roleArn string) string { + return acctest.ConfigCompose( + acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), + testAccGameliftGameServerGroupIamConfig(rName, roleArn), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + content { + instance_type = instance_definition.value + } + } + launch_template { + id = aws_launch_template.test.id + } + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.%[2]s.arn + depends_on = [aws_iam_role_policy_attachment.%[2]s] +} +`, rName, roleArn)) +} + +func testAccGameliftGameServerGroupConfigVpcSubnets(rName string, count int) string { + return acctest.ConfigCompose( + acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), + testAccGameliftGameServerGroupIamConfig(rName, "test"), + testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), + testAccGameliftGameServerGroupLaunchTemplateConfig(rName), + fmt.Sprintf(` +data "aws_vpc" "test" { + default = true +} +data "aws_subnet_ids" "test" { + vpc_id = data.aws_vpc.test.id +} +resource "aws_gamelift_game_server_group" "test" { + game_server_group_name = %[1]q + dynamic "instance_definition" { + for_each = data.aws_ec2_instance_type_offerings.available.instance_types + content { + instance_type = instance_definition.value + } + } + launch_template { + id = aws_launch_template.test.id + } + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn + vpc_subnets = slice(tolist(data.aws_subnet_ids.test.ids), 0, %[2]d) + depends_on = [aws_iam_role_policy_attachment.test] +} +`, rName, count)) +} diff --git a/internal/service/gamelift/status.go b/internal/service/gamelift/status.go index bd4dd11888e..352e9487f2e 100644 --- a/internal/service/gamelift/status.go +++ b/internal/service/gamelift/status.go @@ -38,3 +38,19 @@ func statusFleet(conn *gamelift.GameLift, id string) resource.StateRefreshFunc { return output, aws.StringValue(output.Status), nil } } + +func statusGameServerGroup(conn *gamelift.GameLift, name string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + output, err := FindGameServerGroupByName(conn, name) + + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return output, aws.StringValue(output.Status), nil + } +} diff --git a/internal/service/gamelift/wait.go b/internal/service/gamelift/wait.go index aa56ea61a76..3b16dc226c0 100644 --- a/internal/service/gamelift/wait.go +++ b/internal/service/gamelift/wait.go @@ -7,6 +7,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/gamelift" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) @@ -144,3 +145,47 @@ func isGameliftEventFailure(event *gamelift.Event) bool { } return false } + +func waitGameServerGroupActive(conn *gamelift.GameLift, name string, timeout time.Duration) (*gamelift.GameServerGroup, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{ + gamelift.GameServerGroupStatusNew, + gamelift.GameServerGroupStatusActivating, + }, + Target: []string{gamelift.GameServerGroupStatusActive}, + Refresh: statusGameServerGroup(conn, name), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForState() + + if output, ok := outputRaw.(*gamelift.GameServerGroup); ok { + return output, err + } + + return nil, err +} + +func waitGameServerGroupTerminated(conn *gamelift.GameLift, name string, timeout time.Duration) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{ + gamelift.GameServerGroupStatusDeleteScheduled, + gamelift.GameServerGroupStatusDeleting, + }, + Target: []string{}, + Refresh: statusGameServerGroup(conn, name), + Timeout: timeout, + } + + _, err := stateConf.WaitForState() + + if tfawserr.ErrCodeEquals(err, gamelift.ErrCodeNotFoundException) { + return nil + } + + if err != nil { + return fmt.Errorf("error deleting GameLift Game Server Group (%s): %w", name, err) + } + + return nil +} From 08e871331ea9722732e0106fbbe48c860d83fae8 Mon Sep 17 00:00:00 2001 From: Andrew Johnston Date: Wed, 9 Mar 2022 20:24:17 -0500 Subject: [PATCH 105/229] chore: add sweeper for aws_gamelift_game_server_group --- internal/service/gamelift/sweep.go | 59 ++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/internal/service/gamelift/sweep.go b/internal/service/gamelift/sweep.go index e8b432441e2..0d5f311b08d 100644 --- a/internal/service/gamelift/sweep.go +++ b/internal/service/gamelift/sweep.go @@ -42,6 +42,11 @@ func init() { F: sweepFleets, }) + resource.AddTestSweepers("aws_gamelift_game_server_group", &resource.Sweeper{ + Name: "aws_gamelift_game_server_group", + F: sweepGameServerGroups, + }) + resource.AddTestSweepers("aws_gamelift_game_session_queue", &resource.Sweeper{ Name: "aws_gamelift_game_session_queue", F: sweepGameSessionQueue, @@ -214,6 +219,60 @@ func sweepFleets(region string) error { return errs.ErrorOrNil() } +func sweepGameServerGroups(region string) error { + client, err := sweep.SharedRegionalSweepClient(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*conns.AWSClient).GameLiftConn + sweepResources := make([]*sweep.SweepResource, 0) + var errs *multierror.Error + + input := &gamelift.ListGameServerGroupsInput{} + + for { + output, err := conn.ListGameServerGroups(input) + + for _, gameServerGroup := range output.GameServerGroups { + r := ResourceGameServerGroup() + d := r.Data(nil) + + id := aws.StringValue(gameServerGroup.GameServerGroupName) + d.SetId(id) + + if err != nil { + err := fmt.Errorf("error reading GameLift Game Server Group (%s): %w", id, err) + log.Printf("[ERROR] %s", err) + errs = multierror.Append(errs, err) + continue + } + + sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) + } + + if aws.StringValue(output.NextToken) == "" { + break + } + + input.NextToken = output.NextToken + } + + if err != nil { + errs = multierror.Append(errs, fmt.Errorf("error listing GameLift Game Server Group for %s: %w", region, err)) + } + + if err := sweep.SweepOrchestrator(sweepResources); err != nil { + errs = multierror.Append(errs, fmt.Errorf("error sweeping GameLift Game Server Group for %s: %w", region, err)) + } + + if sweep.SkipSweepError(err) { + log.Printf("[WARN] Skipping GameLift Game Server Group sweep for %s: %s", region, errs) + return nil + } + + return errs.ErrorOrNil() +} + func sweepGameSessionQueue(region string) error { client, err := sweep.SharedRegionalSweepClient(region) if err != nil { From 42206aa64077cf5253ae70cc2aba9846e55faad6 Mon Sep 17 00:00:00 2001 From: Andrew Johnston Date: Wed, 9 Mar 2022 20:42:41 -0500 Subject: [PATCH 106/229] docs: added resource for gamelift game server groups --- .../r/gamelift_game_server_group.markdown | 204 ++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 website/docs/r/gamelift_game_server_group.markdown diff --git a/website/docs/r/gamelift_game_server_group.markdown b/website/docs/r/gamelift_game_server_group.markdown new file mode 100644 index 00000000000..61c32e31ec3 --- /dev/null +++ b/website/docs/r/gamelift_game_server_group.markdown @@ -0,0 +1,204 @@ +--- +subcategory: "Gamelift" +layout: "aws" +page_title: "AWS: aws_gamelift_game_server_group" +description: |- + Provides a Gamelift Game Server Group resource. +--- + +# Resource: aws_gamelift_game_server_group + +Provides an Gamelift Game Server Group resource. + +## Example Usage + +```terraform +resource "aws_gamelift_game_server_group" "example" { + game_server_group_name = "example" + + instance_definition { + instance_type = "c5.large" + } + + instance_definition { + instance_type = "c5a.large" + } + + launch_template { + id = aws_launch_template.example.id + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.example.arn + + depends_on = [ + aws_iam_role_policy_attachment.example + ] +} +``` + +Full usage: + +```terraform +resource "aws_gamelift_game_server_group" "example" { + auto_scaling_policy { + estimated_instance_warmup = 60 + target_tracking_configuration { + target_value = 75 + } + } + + balancing_strategy = "SPOT_ONLY" + game_server_group_name = "example" + game_server_protection_policy = "FULL_PROTECTION" + + instance_definition { + instance_type = "c5.large" + weighted_capacity = "1" + } + + instance_definition { + instance_type = "c5.2xlarge" + weighted_capacity = "2" + } + + launch_template { + id = aws_launch_template.example.id + version = "1" + } + + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.example.arn + + tags = { + Name = "example" + } + + vpc_subnets = [ + "subnet-12345678", + "subnet-23456789" + ] + + depends_on = [ + aws_iam_role_policy_attachment.example + ] +} +``` + +### Example IAM Role for Gamelift Game Server Group + +```terraform +data "aws_partition" "current" {} +resource "aws_iam_role" "example" { + assume_role_policy = <<-EOF + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": [ + "autoscaling.amazonaws.com", + "gamelift.amazonaws.com" + ] + }, + "Action": "sts:AssumeRole" + } + ] + } + EOF + name = "gamelift-game-server-group-example" +} +resource "aws_iam_role_policy_attachment" "example" { + policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/GameLiftGameServerGroupPolicy" + role = aws_iam_role.example.name +} +``` + +## Argument Reference + +The following arguments are supported: + +* `balancing_strategy` - (Optional) Indicates how GameLift FleetIQ balances the use of Spot Instances and On-Demand Instances. + Valid values: `SPOT_ONLY`, `SPOT_PREFERRED`, `ON_DEMAND_ONLY`. Defaults to `SPOT_PREFERRED`. +* `game_server_group_name` - (Required) Name of the game server group. + This value is used to generate unique ARN identifiers for the EC2 Auto Scaling group and the GameLift FleetIQ game server group. +* `game_server_protection_policy` - (Optional) Indicates whether instances in the game server group are protected from early termination. + Unprotected instances that have active game servers running might be terminated during a scale-down event, + causing players to be dropped from the game. + Protected instances cannot be terminated while there are active game servers running except in the event + of a forced game server group deletion. + Valid values: `NO_PROTECTION`, `FULL_PROTECTION`. Defaults to `NO_PROTECTION`. +* `max_size` - (Required) The maximum number of instances allowed in the EC2 Auto Scaling group. + During automatic scaling events, GameLift FleetIQ and EC2 do not scale up the group above this maximum. +* `min_size` - (Required) The minimum number of instances allowed in the EC2 Auto Scaling group. + During automatic scaling events, GameLift FleetIQ and EC2 do not scale down the group below this minimum. +* `role_arn` - (Required) ARN for an IAM role that allows Amazon GameLift to access your EC2 Auto Scaling groups. +* `tags` - (Optional) Key-value map of resource tags +* `vpc_subnets` - (Optional) A list of VPC subnets to use with instances in the game server group. + By default, all GameLift FleetIQ-supported Availability Zones are used. + +### `auto_scaling_policy` + +Configuration settings to define a scaling policy for the Auto Scaling group that is optimized for game hosting. +The scaling policy uses the metric `PercentUtilizedGameServers` to maintain a buffer of idle game servers that +can immediately accommodate new games and players. + +* `estimated_instance_warmup` - (Optional) Length of time, in seconds, it takes for a new instance to start + new game server processes and register with GameLift FleetIQ. + Specifying a warm-up time can be useful, particularly with game servers that take a long time to start up, + because it avoids prematurely starting new instances. Defaults to `60`. + +#### `target_tracking_configuration` + +Settings for a target-based scaling policy applied to Auto Scaling group. +These settings are used to create a target-based policy that tracks the GameLift FleetIQ metric `PercentUtilizedGameServers` +and specifies a target value for the metric. + +* `target_value` - (Required) Desired value to use with a game server group target-based scaling policy. + +### `instance_definition` + +The EC2 instance types and sizes to use in the Auto Scaling group. +The instance definitions must specify at least two different instance types that are supported by GameLift FleetIQ. + +* `instance_type` - (Required) An EC2 instance type. +* `weighted_capacity` - (Optional) Instance weighting that indicates how much this instance type contributes + to the total capacity of a game server group. + Instance weights are used by GameLift FleetIQ to calculate the instance type's cost per unit hour and better identify + the most cost-effective options. + +### `launch_template` + +The EC2 launch template that contains configuration settings and game server code to be deployed to all instances in the game server group. +You can specify the template using either the template name or ID. + +* `id` - (Optional) A unique identifier for an existing EC2 launch template. +* `name` - (Optional) A readable identifier for an existing EC2 launch template. +* `version` - (Optional) The version of the EC2 launch template to use. If none is set, the default is the first version created. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The name of the Gamelift Game Server Group. +* `arn` - The ARN of the Gamelift Game Server Group. +* `auto_scaling_group_arn` - The ARN of the created EC2 Auto Scaling group. + +## Timeouts + +`aws_gamelift_game_server_group` provides the following +[Timeouts](https://www.terraform.io/docs/configuration/blocks/resources/syntax.html#operation-timeouts) configuration options: + +* `create` - (Default `10 minutes`) How long to wait for the Gamelift Game Server Group to be created. +* `delete` - (Default `30 minutes`) How long to wait for the Gamelift Game Server Group to be deleted. + +## Import + +Gamelift Game Server Group can be imported using the `name`, e.g. + +``` +$ terraform import aws_gamelift_game_server_group.example example +``` From 73b6700c7df463f211567fd25288b162d9fcba7c Mon Sep 17 00:00:00 2001 From: Andrew Johnston Date: Wed, 9 Mar 2022 20:47:55 -0500 Subject: [PATCH 107/229] chore: add changelog for 23606 --- .changelog/23606.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/23606.txt diff --git a/.changelog/23606.txt b/.changelog/23606.txt new file mode 100644 index 00000000000..7827744e5db --- /dev/null +++ b/.changelog/23606.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_gamelift_game_server_group +``` From daf098a35d47ca4e89309f1232732021cfc06858 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 10 Mar 2022 09:34:49 -0500 Subject: [PATCH 108/229] d/aws_networkmanager_link: New data source. Acceptance test output: % make testacc TESTS=TestAccNetworkManagerLinkDataSource_ PKG=networkmanager ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/networkmanager/... -v -count 1 -parallel 20 -run='TestAccNetworkManagerLinkDataSource_' -timeout 180m === RUN TestAccNetworkManagerLinkDataSource_basic === PAUSE TestAccNetworkManagerLinkDataSource_basic === CONT TestAccNetworkManagerLinkDataSource_basic --- PASS: TestAccNetworkManagerLinkDataSource_basic (23.73s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 29.249s --- .changelog/13251.txt | 4 + internal/provider/provider.go | 1 + .../networkmanager/link_data_source.go | 98 +++++++++++++++++++ .../networkmanager/link_data_source_test.go | 80 +++++++++++++++ .../docs/d/networkmanager_link.html.markdown | 42 ++++++++ 5 files changed, 225 insertions(+) create mode 100644 internal/service/networkmanager/link_data_source.go create mode 100644 internal/service/networkmanager/link_data_source_test.go create mode 100644 website/docs/d/networkmanager_link.html.markdown diff --git a/.changelog/13251.txt b/.changelog/13251.txt index a121af84bdd..6a5efe3305d 100644 --- a/.changelog/13251.txt +++ b/.changelog/13251.txt @@ -40,4 +40,8 @@ aws_networkmanager_device ```release-note:new-data-source aws_networkmanager_devices +``` + +```release-note:new-data-source +aws_networkmanager_link ``` \ No newline at end of file diff --git a/internal/provider/provider.go b/internal/provider/provider.go index dd445f44c99..66f6e66add2 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -717,6 +717,7 @@ func Provider() *schema.Provider { "aws_networkmanager_devices": networkmanager.DataSourceDevices(), "aws_networkmanager_global_network": networkmanager.DataSourceGlobalNetwork(), "aws_networkmanager_global_networks": networkmanager.DataSourceGlobalNetworks(), + "aws_networkmanager_link": networkmanager.DataSourceLink(), "aws_networkmanager_site": networkmanager.DataSourceSite(), "aws_networkmanager_sites": networkmanager.DataSourceSites(), diff --git a/internal/service/networkmanager/link_data_source.go b/internal/service/networkmanager/link_data_source.go new file mode 100644 index 00000000000..087cb471b16 --- /dev/null +++ b/internal/service/networkmanager/link_data_source.go @@ -0,0 +1,98 @@ +package networkmanager + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" +) + +func DataSourceLink() *schema.Resource { + return &schema.Resource{ + ReadWithoutTimeout: dataSourceLinkRead, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "bandwidth": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "download_speed": { + Type: schema.TypeInt, + Computed: true, + }, + "upload_speed": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "global_network_id": { + Type: schema.TypeString, + Required: true, + }, + "link_id": { + Type: schema.TypeString, + Required: true, + }, + "provider_name": { + Type: schema.TypeString, + Computed: true, + }, + "site_id": { + Type: schema.TypeString, + Computed: true, + }, + "tags": tftags.TagsSchemaComputed(), + "type": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourceLinkRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig + + globalNetworkID := d.Get("global_network_id").(string) + linkID := d.Get("link_id").(string) + link, err := FindLinkByTwoPartKey(ctx, conn, globalNetworkID, linkID) + + if err != nil { + return diag.Errorf("error reading Network Manager Link (%s): %s", linkID, err) + } + + d.SetId(linkID) + d.Set("arn", link.LinkArn) + if link.Bandwidth != nil { + if err := d.Set("bandwidth", []interface{}{flattenBandwidth(link.Bandwidth)}); err != nil { + return diag.Errorf("error setting bandwidth: %s", err) + } + } else { + d.Set("bandwidth", nil) + } + d.Set("description", link.Description) + d.Set("global_network_id", link.GlobalNetworkId) + d.Set("provider_name", link.Provider) + d.Set("site_id", link.SiteId) + d.Set("type", link.Type) + + if err := d.Set("tags", KeyValueTags(link.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return diag.Errorf("error setting tags: %s", err) + } + + return nil +} diff --git a/internal/service/networkmanager/link_data_source_test.go b/internal/service/networkmanager/link_data_source_test.go new file mode 100644 index 00000000000..7b9bc3ba0bd --- /dev/null +++ b/internal/service/networkmanager/link_data_source_test.go @@ -0,0 +1,80 @@ +package networkmanager_test + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/networkmanager" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" +) + +func TestAccNetworkManagerLinkDataSource_basic(t *testing.T) { + dataSourceName := "data.aws_networkmanager_link.test" + resourceName := "aws_networkmanager_link.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccLinkDataSourceConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(dataSourceName, "bandwidth.#", resourceName, "bandwidth.#"), + resource.TestCheckResourceAttrPair(dataSourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttrPair(dataSourceName, "global_network_id", resourceName, "global_network_id"), + resource.TestCheckResourceAttrPair(dataSourceName, "link_id", resourceName, "id"), + resource.TestCheckResourceAttrPair(dataSourceName, "provider_name", resourceName, "provider_name"), + resource.TestCheckResourceAttrPair(dataSourceName, "site_id", resourceName, "site_id"), + resource.TestCheckResourceAttrPair(dataSourceName, "tags.%", resourceName, "tags.%"), + resource.TestCheckResourceAttrPair(dataSourceName, "type", resourceName, "type"), + ), + }, + }, + }) +} + +func testAccLinkDataSourceConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_link" "test" { + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id + + bandwidth { + download_speed = 50 + upload_speed = 10 + } + + description = "description1" + provider_name = "provider1" + type = "type1" + + tags = { + Name = %[1]q + } +} + +data "aws_networkmanager_link" "test" { + global_network_id = aws_networkmanager_global_network.test.id + link_id = aws_networkmanager_link.test.id +} +`, rName) +} diff --git a/website/docs/d/networkmanager_link.html.markdown b/website/docs/d/networkmanager_link.html.markdown new file mode 100644 index 00000000000..de43bec99a9 --- /dev/null +++ b/website/docs/d/networkmanager_link.html.markdown @@ -0,0 +1,42 @@ +--- +subcategory: "Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_link" +description: |- + Retrieve information about a link. +--- + +# Data Source: aws_networkmanager_site + +Retrieve information about a site. + +## Example Usage + +```terraform +data "aws_networkmanager_link" "example" { + global_network_id = var.global_network_id + link_id = var.link_id +} +``` + +## Argument Reference + +* `global_network_id` - (Required) The ID of the Global Network of the link to retrieve. +* `link_id` - (Required) The id of the specific link to retrieve. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - The ARN of the link. +* `bandwidth` - The upload speed and download speed of the link as documented below +* `description` - The description of the link. +* `provider_name` - The provider of the link. +* `site_id` - The ID of the site. +* `tags` - Key-value tags for the link. +* `type` - The type of the link. + +The `bandwidth` object supports the following: + +* `download_speed` - Download speed in Mbps. +* `upload_speed` - Upload speed in Mbps. From 4a3521c6119bfcfaedaa6d9e1cd765e22b2db76b Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 10 Mar 2022 11:57:36 -0500 Subject: [PATCH 109/229] d/aws_networkmanager_links: New data source. Acceptance test output: % make testacc TESTS=TestAccNetworkManagerLinksDataSource_ PKG=networkmanager ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/networkmanager/... -v -count 1 -parallel 20 -run='TestAccNetworkManagerLinksDataSource_' -timeout 180m === RUN TestAccNetworkManagerLinksDataSource_basic === PAUSE TestAccNetworkManagerLinksDataSource_basic === CONT TestAccNetworkManagerLinksDataSource_basic --- PASS: TestAccNetworkManagerLinksDataSource_basic (48.90s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 52.580s --- .changelog/13251.txt | 4 + internal/provider/provider.go | 1 + .../networkmanager/links_data_source.go | 88 ++++++++++++++++++ .../networkmanager/links_data_source_test.go | 90 +++++++++++++++++++ .../docs/d/networkmanager_links.html.markdown | 37 ++++++++ 5 files changed, 220 insertions(+) create mode 100644 internal/service/networkmanager/links_data_source.go create mode 100644 internal/service/networkmanager/links_data_source_test.go create mode 100644 website/docs/d/networkmanager_links.html.markdown diff --git a/.changelog/13251.txt b/.changelog/13251.txt index 6a5efe3305d..a65c715816e 100644 --- a/.changelog/13251.txt +++ b/.changelog/13251.txt @@ -44,4 +44,8 @@ aws_networkmanager_devices ```release-note:new-data-source aws_networkmanager_link +``` + +```release-note:new-data-source +aws_networkmanager_links ``` \ No newline at end of file diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 66f6e66add2..0d329278326 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -718,6 +718,7 @@ func Provider() *schema.Provider { "aws_networkmanager_global_network": networkmanager.DataSourceGlobalNetwork(), "aws_networkmanager_global_networks": networkmanager.DataSourceGlobalNetworks(), "aws_networkmanager_link": networkmanager.DataSourceLink(), + "aws_networkmanager_links": networkmanager.DataSourceLinks(), "aws_networkmanager_site": networkmanager.DataSourceSite(), "aws_networkmanager_sites": networkmanager.DataSourceSites(), diff --git a/internal/service/networkmanager/links_data_source.go b/internal/service/networkmanager/links_data_source.go new file mode 100644 index 00000000000..303263f2394 --- /dev/null +++ b/internal/service/networkmanager/links_data_source.go @@ -0,0 +1,88 @@ +package networkmanager + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" +) + +func DataSourceLinks() *schema.Resource { + return &schema.Resource{ + ReadWithoutTimeout: dataSourceLinksRead, + + Schema: map[string]*schema.Schema{ + "global_network_id": { + Type: schema.TypeString, + Required: true, + }, + "ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "provider_name": { + Type: schema.TypeString, + Optional: true, + }, + "site_id": { + Type: schema.TypeString, + Optional: true, + }, + "tags": tftags.TagsSchema(), + "type": { + Type: schema.TypeString, + Optional: true, + }, + }, + } +} + +func dataSourceLinksRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig + tagsToMatch := tftags.New(d.Get("tags").(map[string]interface{})).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) + + input := &networkmanager.GetLinksInput{ + GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), + } + + if v, ok := d.GetOk("provider_name"); ok { + input.Provider = aws.String(v.(string)) + } + + if v, ok := d.GetOk("site_id"); ok { + input.SiteId = aws.String(v.(string)) + } + + if v, ok := d.GetOk("type"); ok { + input.Type = aws.String(v.(string)) + } + + output, err := FindLinks(ctx, conn, input) + + if err != nil { + return diag.Errorf("error listing Network Manager Sites: %s", err) + } + + var linkIDs []string + + for _, v := range output { + if len(tagsToMatch) > 0 { + if !KeyValueTags(v.Tags).ContainsAll(tagsToMatch) { + continue + } + } + + linkIDs = append(linkIDs, aws.StringValue(v.LinkId)) + } + + d.SetId(meta.(*conns.AWSClient).Region) + d.Set("ids", linkIDs) + + return nil +} diff --git a/internal/service/networkmanager/links_data_source_test.go b/internal/service/networkmanager/links_data_source_test.go new file mode 100644 index 00000000000..a507d4bef9b --- /dev/null +++ b/internal/service/networkmanager/links_data_source_test.go @@ -0,0 +1,90 @@ +package networkmanager_test + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/networkmanager" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" +) + +func TestAccNetworkManagerLinksDataSource_basic(t *testing.T) { + dataSourceAllName := "data.aws_networkmanager_links.all" + dataSourceByTagsName := "data.aws_networkmanager_links.by_tags" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccLinksDataSourceConfig(rName), + Check: resource.ComposeTestCheckFunc( + acctest.CheckResourceAttrGreaterThanValue(dataSourceAllName, "ids.#", "1"), + resource.TestCheckResourceAttr(dataSourceByTagsName, "ids.#", "1"), + ), + }, + }, + }) +} + +func testAccLinksDataSourceConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_link" "test1" { + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id + + bandwidth { + download_speed = 50 + upload_speed = 10 + } +} + +resource "aws_networkmanager_link" "test2" { + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id + + bandwidth { + download_speed = 75 + upload_speed = 25 + } + + tags = { + Name = %[1]q + } +} + +data "aws_networkmanager_links" "all" { + global_network_id = aws_networkmanager_global_network.test.id + + depends_on = [aws_networkmanager_link.test1, aws_networkmanager_link.test2] +} + +data "aws_networkmanager_links" "by_tags" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } + + depends_on = [aws_networkmanager_link.test1, aws_networkmanager_link.test2] +} +`, rName) +} diff --git a/website/docs/d/networkmanager_links.html.markdown b/website/docs/d/networkmanager_links.html.markdown new file mode 100644 index 00000000000..49c362da3ac --- /dev/null +++ b/website/docs/d/networkmanager_links.html.markdown @@ -0,0 +1,37 @@ +--- +subcategory: "Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_links" +description: |- + Retrieve information about links. +--- + +# Data Source: aws_networkmanager_links + +Retrieve information about link. + +## Example Usage + +```terraform +data "aws_networkmanager_links" "example" { + global_network_id = var.global_network_id + + tags = { + Env = "test" + } +} +``` + +## Argument Reference + +* `global_network_id` - (Required) The ID of the Global Network of the links to retrieve. +* `provider_name` - (Optional) The link provider to retrieve. +* `site_id` - (Optional) The ID of the site of the links to retrieve. +* `tags` - (Optional) Restricts the list to the links with these tags. +* `type` - (Optional) The link type to retrieve. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `ids` - The IDs of the links. From aa3d55a4c802f46e7b25db46e15d41abda61a139 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 10 Mar 2022 14:50:54 -0500 Subject: [PATCH 110/229] r/aws_networkmanager_link_association: New resource. Acceptance test output: % make testacc TESTS=TestAccNetworkManagerLinkAssociation_ PKG=networkmanager ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/networkmanager/... -v -count 1 -parallel 20 -run='TestAccNetworkManagerLinkAssociation_' -timeout 180m === RUN TestAccNetworkManagerLinkAssociation_basic === PAUSE TestAccNetworkManagerLinkAssociation_basic === RUN TestAccNetworkManagerLinkAssociation_disappears === PAUSE TestAccNetworkManagerLinkAssociation_disappears === CONT TestAccNetworkManagerLinkAssociation_basic === CONT TestAccNetworkManagerLinkAssociation_disappears --- PASS: TestAccNetworkManagerLinkAssociation_disappears (24.07s) --- PASS: TestAccNetworkManagerLinkAssociation_basic (28.72s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 32.548s --- .changelog/13251.txt | 4 + internal/provider/provider.go | 1 + .../networkmanager/link_association.go | 291 ++++++++++++++++++ .../networkmanager/link_association_test.go | 169 ++++++++++ ...workmanager_link_association.html.markdown | 43 +++ 5 files changed, 508 insertions(+) create mode 100644 internal/service/networkmanager/link_association.go create mode 100644 internal/service/networkmanager/link_association_test.go create mode 100644 website/docs/r/networkmanager_link_association.html.markdown diff --git a/.changelog/13251.txt b/.changelog/13251.txt index a65c715816e..7098f9f1fae 100644 --- a/.changelog/13251.txt +++ b/.changelog/13251.txt @@ -18,6 +18,10 @@ aws_networkmanager_transit_gateway_registration aws_networkmanager_link ``` +```release-note:new-resource +aws_networkmanager_link_association +``` + ```release-note:new-data-source aws_networkmanager_global_network ``` diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 0d329278326..88e0b35bf20 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1589,6 +1589,7 @@ func Provider() *schema.Provider { "aws_networkmanager_device": networkmanager.ResourceDevice(), "aws_networkmanager_global_network": networkmanager.ResourceGlobalNetwork(), "aws_networkmanager_link": networkmanager.ResourceLink(), + "aws_networkmanager_link_association": networkmanager.ResourceLinkAssociation(), "aws_networkmanager_site": networkmanager.ResourceSite(), "aws_networkmanager_transit_gateway_registration": networkmanager.ResourceTransitGatewayRegistration(), diff --git a/internal/service/networkmanager/link_association.go b/internal/service/networkmanager/link_association.go new file mode 100644 index 00000000000..57adcc8541a --- /dev/null +++ b/internal/service/networkmanager/link_association.go @@ -0,0 +1,291 @@ +package networkmanager + +import ( + "context" + "fmt" + "log" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" +) + +func ResourceLinkAssociation() *schema.Resource { + return &schema.Resource{ + CreateWithoutTimeout: resourceLinkAssociationCreate, + ReadWithoutTimeout: resourceLinkAssociationRead, + DeleteWithoutTimeout: resourceLinkAssociationDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "device_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "global_network_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "link_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + } +} + +func resourceLinkAssociationCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + globalNetworkID := d.Get("global_network_id").(string) + linkID := d.Get("link_id").(string) + deviceID := d.Get("device_id").(string) + id := LinkAssociationCreateResourceID(globalNetworkID, linkID, deviceID) + input := &networkmanager.AssociateLinkInput{ + DeviceId: aws.String(deviceID), + GlobalNetworkId: aws.String(globalNetworkID), + LinkId: aws.String(linkID), + } + + log.Printf("[DEBUG] Creating Network Manager Link Association: %s", input) + _, err := conn.AssociateLinkWithContext(ctx, input) + + if err != nil { + return diag.Errorf("error creating Network Manager Link Association (%s): %s", id, err) + } + + d.SetId(id) + + if _, err := waitLinkAssociationCreated(ctx, conn, globalNetworkID, linkID, deviceID, d.Timeout(schema.TimeoutCreate)); err != nil { + return diag.Errorf("error waiting for Network Manager Link Association (%s) create: %s", d.Id(), err) + } + + return resourceLinkAssociationRead(ctx, d, meta) +} + +func resourceLinkAssociationRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + globalNetworkID, linkID, deviceID, err := LinkAssociationParseResourceID(d.Id()) + + if err != nil { + return diag.FromErr(err) + } + + output, err := FindLinkAssociationByThreePartKey(ctx, conn, globalNetworkID, linkID, deviceID) + + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Network Manager Link Association %s not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return diag.Errorf("error reading Network Manager Link Association (%s): %s", d.Id(), err) + } + + d.Set("device_id", output.DeviceId) + d.Set("global_network_id", output.GlobalNetworkId) + d.Set("link_id", output.LinkId) + + return nil +} + +func resourceLinkAssociationDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + globalNetworkID, linkID, deviceID, err := LinkAssociationParseResourceID(d.Id()) + + if err != nil { + return diag.FromErr(err) + } + + log.Printf("[DEBUG] Deleting Network Manager Link Association: %s", d.Id()) + _, err = conn.DisassociateLinkWithContext(ctx, &networkmanager.DisassociateLinkInput{ + DeviceId: aws.String(deviceID), + GlobalNetworkId: aws.String(globalNetworkID), + LinkId: aws.String(linkID), + }) + + if globalNetworkIDNotFoundError(err) || tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeResourceNotFoundException) { + return nil + } + + if err != nil { + return diag.Errorf("error deleting Network Manager Link Association (%s): %s", d.Id(), err) + } + + if _, err := waitLinkAssociationDeleted(ctx, conn, globalNetworkID, linkID, deviceID, d.Timeout(schema.TimeoutCreate)); err != nil { + return diag.Errorf("error waiting for Network Manager Link Association (%s) delete: %s", d.Id(), err) + } + + return nil +} + +func FindLinkAssociation(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.GetLinkAssociationsInput) (*networkmanager.LinkAssociation, error) { + output, err := FindLinkAssociations(ctx, conn, input) + + if err != nil { + return nil, err + } + + if len(output) == 0 || output[0] == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } + + return output[0], nil +} + +func FindLinkAssociations(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.GetLinkAssociationsInput) ([]*networkmanager.LinkAssociation, error) { + var output []*networkmanager.LinkAssociation + + err := conn.GetLinkAssociationsPagesWithContext(ctx, input, func(page *networkmanager.GetLinkAssociationsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.LinkAssociations { + if v == nil { + continue + } + + output = append(output, v) + } + + return !lastPage + }) + + if globalNetworkIDNotFoundError(err) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + return output, nil +} + +func FindLinkAssociationByThreePartKey(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, linkID, deviceID string) (*networkmanager.LinkAssociation, error) { + input := &networkmanager.GetLinkAssociationsInput{ + DeviceId: aws.String(deviceID), + GlobalNetworkId: aws.String(globalNetworkID), + LinkId: aws.String(linkID), + } + + output, err := FindLinkAssociation(ctx, conn, input) + + if err != nil { + return nil, err + } + + if state := aws.StringValue(output.LinkAssociationState); state == networkmanager.LinkAssociationStateDeleted { + return nil, &resource.NotFoundError{ + Message: state, + LastRequest: input, + } + } + + // Eventual consistency check. + if aws.StringValue(output.GlobalNetworkId) != globalNetworkID || aws.StringValue(output.LinkId) != linkID || aws.StringValue(output.DeviceId) != deviceID { + return nil, &resource.NotFoundError{ + LastRequest: input, + } + } + + return output, nil +} + +func statusLinkAssociationState(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, linkID, deviceID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + output, err := FindLinkAssociationByThreePartKey(ctx, conn, globalNetworkID, linkID, deviceID) + + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return output, aws.StringValue(output.LinkAssociationState), nil + } +} + +func waitLinkAssociationCreated(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, linkID, deviceID string, timeout time.Duration) (*networkmanager.LinkAssociation, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.LinkAssociationStatePending}, + Target: []string{networkmanager.LinkAssociationStateAvailable}, + Timeout: timeout, + Refresh: statusLinkAssociationState(ctx, conn, globalNetworkID, linkID, deviceID), + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*networkmanager.LinkAssociation); ok { + return output, err + } + + return nil, err +} + +func waitLinkAssociationDeleted(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, linkID, deviceID string, timeout time.Duration) (*networkmanager.LinkAssociation, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.LinkAssociationStateDeleting}, + Target: []string{}, + Timeout: timeout, + Refresh: statusLinkAssociationState(ctx, conn, globalNetworkID, linkID, deviceID), + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*networkmanager.LinkAssociation); ok { + return output, err + } + + return nil, err +} + +const linkAssociationIDSeparator = "," + +func LinkAssociationCreateResourceID(globalNetworkID, linkID, deviceID string) string { + parts := []string{globalNetworkID, linkID, deviceID} + id := strings.Join(parts, linkAssociationIDSeparator) + + return id +} + +func LinkAssociationParseResourceID(id string) (string, string, string, error) { + parts := strings.Split(id, linkAssociationIDSeparator) + + if len(parts) == 3 && parts[0] != "" && parts[1] != "" && parts[2] != "" { + return parts[0], parts[1], parts[2], nil + } + + return "", "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected GLOBAL-NETWORK-ID%[2]sLINK-ID%[2]sDEVICE-ID", id, linkAssociationIDSeparator) +} diff --git a/internal/service/networkmanager/link_association_test.go b/internal/service/networkmanager/link_association_test.go new file mode 100644 index 00000000000..e61c0d73533 --- /dev/null +++ b/internal/service/networkmanager/link_association_test.go @@ -0,0 +1,169 @@ +package networkmanager_test + +import ( + "context" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/networkmanager" + 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" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tfnetworkmanager "github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" +) + +func TestAccNetworkManagerLinkAssociation_basic(t *testing.T) { + resourceName := "aws_networkmanager_link_association.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckLinkAssociationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccLinkAssociationConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckLinkAssociationExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccNetworkManagerLinkAssociation_disappears(t *testing.T) { + resourceName := "aws_networkmanager_link_association.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckLinkAssociationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccLinkAssociationConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckLinkAssociationExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfnetworkmanager.ResourceLinkAssociation(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccCheckLinkAssociationDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_networkmanager_link_association" { + continue + } + + globalNetworkID, linkID, deviceID, err := tfnetworkmanager.LinkAssociationParseResourceID(rs.Primary.ID) + + if err != nil { + return err + } + + _, err = tfnetworkmanager.FindLinkAssociationByThreePartKey(context.TODO(), conn, globalNetworkID, linkID, deviceID) + + if tfresource.NotFound(err) { + continue + } + + if err != nil { + return err + } + + return fmt.Errorf("Network Manager Link Association %s still exists", rs.Primary.ID) + } + + return nil +} + +func testAccCheckLinkAssociationExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No Network Manager Link Association ID is set") + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn + + globalNetworkID, linkID, deviceID, err := tfnetworkmanager.LinkAssociationParseResourceID(rs.Primary.ID) + + if err != nil { + return err + } + + _, err = tfnetworkmanager.FindLinkAssociationByThreePartKey(context.TODO(), conn, globalNetworkID, linkID, deviceID) + + if err != nil { + return err + } + + return nil + } +} + +func testAccLinkAssociationConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_link" "test" { + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id + + bandwidth { + download_speed = 50 + upload_speed = 10 + } + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_device" "test" { + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_link_association" "test" { + global_network_id = aws_networkmanager_global_network.test.id + link_id = aws_networkmanager_link.test.id + device_id = aws_networkmanager_device.test.id +} +`, rName) +} diff --git a/website/docs/r/networkmanager_link_association.html.markdown b/website/docs/r/networkmanager_link_association.html.markdown new file mode 100644 index 00000000000..dfdd2db2c0c --- /dev/null +++ b/website/docs/r/networkmanager_link_association.html.markdown @@ -0,0 +1,43 @@ +--- +subcategory: "Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_link_association" +description: |- + Associates a link to a device. +--- + +# Resource: aws_networkmanager_link_association + +Associates a link to a device. +A device can be associated to multiple links and a link can be associated to multiple devices. +The device and link must be in the same global network and the same site. + +## Example Usage + +```terraform +resource "aws_networkmanager_link_association" "example" { + global_network_id = aws_networkmanager_global_network.example.id + link_id = aws_networkmanager_link.example.id + device_id = aws_networkmanager_device.example.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `device_id` - (Required) The ID of the device. +* `global_network_id` - (Required) The ID of the global network. +* `link_id` - (Required) The ID of the link. + +## Attributes Reference + +No additional attributes are exported. + +## Import + +`aws_networkmanager_link_association` can be imported using the global network ID, link ID and device ID, e.g. + +``` +$ terraform import aws_networkmanager_link_association.example global-network-0d47f6t230mz46dy4,link-444555aaabbb11223,device-07f6fd08867abc123 +``` From 549cadf9cd936a270ebfdd9b0b22ecd20ec60d1b Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 10 Mar 2022 16:38:37 -0500 Subject: [PATCH 111/229] Sweep Network Manager Link Associations. --- internal/service/networkmanager/sweep.go | 77 ++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/internal/service/networkmanager/sweep.go b/internal/service/networkmanager/sweep.go index 2e73b811774..f5da811169b 100644 --- a/internal/service/networkmanager/sweep.go +++ b/internal/service/networkmanager/sweep.go @@ -36,11 +36,22 @@ func init() { resource.AddTestSweepers("aws_networkmanager_device", &resource.Sweeper{ Name: "aws_networkmanager_device", F: sweepDevices, + Dependencies: []string{ + "aws_networkmanager_link_association", + }, }) resource.AddTestSweepers("aws_networkmanager_link", &resource.Sweeper{ Name: "aws_networkmanager_link", F: sweepLinks, + Dependencies: []string{ + "aws_networkmanager_link_association", + }, + }) + + resource.AddTestSweepers("aws_networkmanager_link_association", &resource.Sweeper{ + Name: "aws_networkmanager_link_association", + F: sweepLinkAssociations, }) } @@ -287,3 +298,69 @@ func sweepLinks(region string) error { return sweeperErrs.ErrorOrNil() } + +func sweepLinkAssociations(region string) error { + client, err := sweep.SharedRegionalSweepClient(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*conns.AWSClient).NetworkManagerConn + input := &networkmanager.DescribeGlobalNetworksInput{} + var sweeperErrs *multierror.Error + sweepResources := make([]*sweep.SweepResource, 0) + + err = conn.DescribeGlobalNetworksPages(input, func(page *networkmanager.DescribeGlobalNetworksOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.GlobalNetworks { + input := &networkmanager.GetLinkAssociationsInput{ + GlobalNetworkId: v.GlobalNetworkId, + } + + err := conn.GetLinkAssociationsPages(input, func(page *networkmanager.GetLinkAssociationsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.LinkAssociations { + r := ResourceLinkAssociation() + d := r.Data(nil) + d.SetId(LinkAssociationCreateResourceID(aws.StringValue(v.GlobalNetworkId), aws.StringValue(v.LinkId), aws.StringValue(v.DeviceId))) + + sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) + } + + return !lastPage + }) + + if sweep.SkipSweepError(err) { + continue + } + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing Network Manager Link Associations (%s): %w", region, err)) + } + } + + return !lastPage + }) + + if sweep.SkipSweepError(err) { + log.Printf("[WARN] Skipping Network Manager Link Association sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing Network Manager Global Networks (%s): %w", region, err)) + } + + err = sweep.SweepOrchestrator(sweepResources) + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error sweeping Network Manager Link Associations (%s): %w", region, err)) + } + + return sweeperErrs.ErrorOrNil() +} From 923fd862bb904f407130f739ab6417adc16b4e4d Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Mar 2022 12:49:28 -0500 Subject: [PATCH 112/229] rds: Fix some acceptance tests --- internal/service/rds/cluster.go | 7 + internal/service/rds/cluster_endpoint_test.go | 22 +- internal/service/rds/cluster_test.go | 2 +- internal/service/rds/global_cluster.go | 5 +- internal/service/rds/global_cluster_test.go | 41 +-- .../service/rds/instance_data_source_test.go | 27 +- internal/service/rds/instance_test.go | 6 +- internal/service/rds/option_group_test.go | 284 +++++++++--------- 8 files changed, 210 insertions(+), 184 deletions(-) diff --git a/internal/service/rds/cluster.go b/internal/service/rds/cluster.go index 16cfd9d0736..d7d9e5874f2 100644 --- a/internal/service/rds/cluster.go +++ b/internal/service/rds/cluster.go @@ -559,6 +559,7 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { } if attr, ok := d.GetOk("engine_version"); ok { + fmt.Printf("[CREATE/cluster/snapshot_identifier] engine_version: %s\n", attr.(string)) opts.EngineVersion = aws.String(attr.(string)) } @@ -654,6 +655,7 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { } if attr, ok := d.GetOk("engine_version"); ok { + fmt.Printf("[CREATE/cluster/s3_import] engine_version: %s\n", attr.(string)) createOpts.EngineVersion = aws.String(attr.(string)) } @@ -871,6 +873,7 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { } if attr, ok := d.GetOk("engine_version"); ok { + fmt.Printf("[CREATE/cluster/else] engine_version: %s\n", attr.(string)) createOpts.EngineVersion = aws.String(attr.(string)) } @@ -1183,6 +1186,7 @@ func resourceClusterUpdate(d *schema.ResourceData, meta interface{}) error { } if d.HasChange("engine_version") { + fmt.Printf("[UPDATE/cluster] engine_version: %s\n", d.Get("engine_version").(string)) req.EngineVersion = aws.String(d.Get("engine_version").(string)) requestUpdate = true } @@ -1549,7 +1553,10 @@ func compareActualEngineVersion(d *schema.ResourceData, oldVersion string, newVe if oldVersion != newVersion && string(append([]byte(oldVersion), []byte(".")...)) != newVersionSubstr { d.Set("engine_version", newVersion) + fmt.Printf("[READ/cluster] engine_version: %s\n", newVersion) } d.Set("engine_version_actual", newVersion) + fmt.Printf("[READ/cluster] engine_version_actual: %s\n", newVersion) + } diff --git a/internal/service/rds/cluster_endpoint_test.go b/internal/service/rds/cluster_endpoint_test.go index 02e74881f79..c463959741a 100644 --- a/internal/service/rds/cluster_endpoint_test.go +++ b/internal/service/rds/cluster_endpoint_test.go @@ -211,7 +211,9 @@ func testAccCheckClusterEndpointExistsWithProvider(resourceName string, endpoint } func testAccClusterEndpointBaseConfig(n int) string { - return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` + return acctest.ConfigCompose( + acctest.ConfigAvailableAZsNoOptIn(), + fmt.Sprintf(` data "aws_rds_orderable_db_instance" "test" { engine = aws_rds_cluster.default.engine engine_version = aws_rds_cluster.default.engine_version @@ -249,7 +251,9 @@ resource "aws_rds_cluster_instance" "test2" { } func testAccClusterEndpointConfig(n int) string { - return testAccClusterEndpointBaseConfig(n) + fmt.Sprintf(` + return acctest.ConfigCompose( + testAccClusterEndpointBaseConfig(n), + fmt.Sprintf(` resource "aws_rds_cluster_endpoint" "reader" { cluster_identifier = aws_rds_cluster.default.id cluster_endpoint_identifier = "reader-%[1]d" @@ -265,11 +269,13 @@ resource "aws_rds_cluster_endpoint" "default" { excluded_members = [aws_rds_cluster_instance.test2.id] } -`, n) +`, n)) } func testAccClusterEndpointTags1Config(n int, tagKey1, tagValue1 string) string { - return testAccClusterEndpointBaseConfig(n) + fmt.Sprintf(` + return acctest.ConfigCompose( + testAccClusterEndpointBaseConfig(n), + fmt.Sprintf(` resource "aws_rds_cluster_endpoint" "reader" { cluster_identifier = aws_rds_cluster.default.id cluster_endpoint_identifier = "reader-%[1]d" @@ -281,11 +287,13 @@ resource "aws_rds_cluster_endpoint" "reader" { %[2]q = %[3]q } } -`, n, tagKey1, tagValue1) +`, n, tagKey1, tagValue1)) } func testAccClusterEndpointTags2Config(n int, tagKey1, tagValue1, tagKey2, tagValue2 string) string { - return testAccClusterEndpointBaseConfig(n) + fmt.Sprintf(` + return acctest.ConfigCompose( + testAccClusterEndpointBaseConfig(n), + fmt.Sprintf(` resource "aws_rds_cluster_endpoint" "reader" { cluster_identifier = aws_rds_cluster.default.id cluster_endpoint_identifier = "reader-%[1]d" @@ -298,5 +306,5 @@ resource "aws_rds_cluster_endpoint" "reader" { %[4]q = %[5]q } } -`, n, tagKey1, tagValue1, tagKey2, tagValue2) +`, n, tagKey1, tagValue1, tagKey2, tagValue2)) } diff --git a/internal/service/rds/cluster_test.go b/internal/service/rds/cluster_test.go index 401660d83e7..0ac9a15bc8a 100644 --- a/internal/service/rds/cluster_test.go +++ b/internal/service/rds/cluster_test.go @@ -3599,7 +3599,7 @@ func testAccClusterConfig_SnapshotIdentifier_EngineVersion(rName string, same bo return fmt.Sprintf(` data "aws_rds_engine_version" "test" { engine = "aurora-postgresql" - preferred_versions = ["11.4", "10.4", "9.6.6"] + preferred_versions = ["13.3", "12.9", "11.14"] } data "aws_rds_engine_version" "upgrade" { diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index 8d5806da3da..674f4e6fa79 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -128,6 +128,7 @@ func resourceGlobalClusterCreate(d *schema.ResourceData, meta interface{}) error } if v, ok := d.GetOk("engine_version"); ok { + fmt.Printf("[CREATE/global_cluster] engine_version: %s\n", v.(string)) input.EngineVersion = aws.String(v.(string)) } @@ -192,6 +193,7 @@ func resourceGlobalClusterRead(d *schema.ResourceData, meta interface{}) error { d.Set("deletion_protection", globalCluster.DeletionProtection) d.Set("engine", globalCluster.Engine) d.Set("engine_version", globalCluster.EngineVersion) + fmt.Printf("[READ/global_cluster] engine_verison: %s\n", aws.StringValue(globalCluster.EngineVersion)) d.Set("global_cluster_identifier", globalCluster.GlobalClusterIdentifier) if err := d.Set("global_cluster_members", flattenGlobalClusterMembers(globalCluster.GlobalClusterMembers)); err != nil { @@ -213,6 +215,7 @@ func resourceGlobalClusterUpdate(d *schema.ResourceData, meta interface{}) error } if d.HasChange("engine_version") { + fmt.Printf("[UPDATE/global_cluster] engine_version: %s\n", d.Get("engine_version").(string)) if err := resourceGlobalClusterUpgradeEngineVersion(d, conn); err != nil { return err } @@ -581,7 +584,7 @@ func resourceGlobalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, } } if err != nil { - return fmt.Errorf("Failed to update engine_version on global cluster member (%s): %s", clusterMemberArn, err) + return fmt.Errorf("failed to update engine_version on RDS Global Cluster member (%s): %s", clusterMemberArn, err) } } } diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index 893f88d74bd..586ffe58f26 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -210,17 +210,17 @@ func TestAccRDSGlobalCluster_engineVersionUpdateMinor(t *testing.T) { CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.6.mysql_aurora.1.22.2"), + Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-mysql", "5.7.mysql_aurora.2.10.1"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), ), }, { - Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.6.mysql_aurora.1.23.2"), + Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-mysql", "5.7.mysql_aurora.2.10.2"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster2), testAccCheckGlobalClusterNotRecreated(&globalCluster1, &globalCluster2), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.6.mysql_aurora.1.23.2"), + resource.TestCheckResourceAttr(resourceName, "engine_version", "5.7.mysql_aurora.2.10.2"), ), }, { @@ -244,18 +244,18 @@ func TestAccRDSGlobalCluster_engineVersionUpdateMajor(t *testing.T) { CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.6.mysql_aurora.1.22.2"), + Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.7.mysql_aurora.2.10.2"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), ), }, { - Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.7.mysql_aurora.2.07.2"), + Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "8.0.mysql_aurora.3.01.0"), ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster2), testAccCheckGlobalClusterNotRecreated(&globalCluster1, &globalCluster2), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.7.mysql_aurora.2.07.2"), + resource.TestCheckResourceAttr(resourceName, "engine_version", "8.0.mysql_aurora.3.01.0"), ), }, { @@ -532,7 +532,7 @@ func testAccPreCheckGlobalCluster(t *testing.T) { func testAccGlobalClusterConfig(rName string) string { return fmt.Sprintf(` resource "aws_rds_global_cluster" "test" { - global_cluster_identifier = %q + global_cluster_identifier = %[1]q } `, rName) } @@ -540,8 +540,8 @@ resource "aws_rds_global_cluster" "test" { func testAccGlobalClusterDatabaseNameConfig(rName, databaseName string) string { return fmt.Sprintf(` resource "aws_rds_global_cluster" "test" { - database_name = %q - global_cluster_identifier = %q + database_name = %[1]q + global_cluster_identifier = %[2]q } `, databaseName, rName) } @@ -549,8 +549,8 @@ resource "aws_rds_global_cluster" "test" { func testAccGlobalClusterDeletionProtectionConfig(rName string, deletionProtection bool) string { return fmt.Sprintf(` resource "aws_rds_global_cluster" "test" { - deletion_protection = %t - global_cluster_identifier = %q + deletion_protection = %[1]t + global_cluster_identifier = %[2]q } `, deletionProtection, rName) } @@ -558,8 +558,8 @@ resource "aws_rds_global_cluster" "test" { func testAccGlobalClusterEngineConfig(rName, engine string) string { return fmt.Sprintf(` resource "aws_rds_global_cluster" "test" { - engine = %q - global_cluster_identifier = %q + engine = %[1]q + global_cluster_identifier = %[2]q } `, engine, rName) } @@ -567,9 +567,9 @@ resource "aws_rds_global_cluster" "test" { func testAccGlobalClusterEngineVersionConfig(rName, engine, engineVersion string) string { return fmt.Sprintf(` resource "aws_rds_global_cluster" "test" { - engine = %q - engine_version = %q - global_cluster_identifier = %q + engine = %[1]q + engine_version = %[2]q + global_cluster_identifier = %[3]q } `, engine, engineVersion, rName) } @@ -586,6 +586,8 @@ resource "aws_rds_cluster" "test" { apply_immediately = true allow_major_version_upgrade = true cluster_identifier = %[3]q + engine = %[1]q + engine_version = %[2]q master_password = "mustbeeightcharacters" master_username = "test" skip_final_snapshot = true @@ -600,6 +602,9 @@ resource "aws_rds_cluster" "test" { resource "aws_rds_cluster_instance" "test" { apply_immediately = true cluster_identifier = aws_rds_cluster.test.id + #cluster_identifier = %[3]q + engine = %[1]q + engine_version = %[2]q identifier = %[3]q instance_class = "db.r3.large" @@ -664,8 +669,8 @@ resource "aws_rds_global_cluster" "test" { func testAccGlobalClusterStorageEncryptedConfig(rName string, storageEncrypted bool) string { return fmt.Sprintf(` resource "aws_rds_global_cluster" "test" { - global_cluster_identifier = %q - storage_encrypted = %t + global_cluster_identifier = %[1]q + storage_encrypted = %[2]t } `, rName, storageEncrypted) } diff --git a/internal/service/rds/instance_data_source_test.go b/internal/service/rds/instance_data_source_test.go index 59164d71ac2..832f18ae86e 100644 --- a/internal/service/rds/instance_data_source_test.go +++ b/internal/service/rds/instance_data_source_test.go @@ -11,14 +11,15 @@ import ( ) func TestAccRDSInstanceDataSource_basic(t *testing.T) { - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), Providers: acctest.Providers, Steps: []resource.TestStep{ { - Config: testAccInstanceDataSourceConfig(rInt), + Config: testAccInstanceDataSourceConfig(rName), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "address"), resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "allocated_storage"), @@ -44,7 +45,7 @@ func TestAccRDSInstanceDataSource_basic(t *testing.T) { } func TestAccRDSInstanceDataSource_ec2Classic(t *testing.T) { - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); acctest.PreCheckEC2Classic(t) }, @@ -52,7 +53,7 @@ func TestAccRDSInstanceDataSource_ec2Classic(t *testing.T) { ProviderFactories: acctest.ProviderFactories, Steps: []resource.TestStep{ { - Config: testAccInstanceDataSourceConfig_ec2Classic(rInt), + Config: testAccInstanceDataSourceConfig_ec2Classic(rName), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr("data.aws_db_instance.bar", "db_subnet_group", ""), ), @@ -61,7 +62,7 @@ func TestAccRDSInstanceDataSource_ec2Classic(t *testing.T) { }) } -func testAccInstanceDataSourceConfig(rInt int) string { +func testAccInstanceDataSourceConfig(rName string) string { return fmt.Sprintf(` data "aws_rds_orderable_db_instance" "test" { engine = "mariadb" @@ -69,7 +70,7 @@ data "aws_rds_orderable_db_instance" "test" { } resource "aws_db_instance" "bar" { - identifier = "datasource-test-terraform-%d" + identifier = %[1]q allocated_storage = 10 engine = data.aws_rds_orderable_db_instance.test.engine @@ -94,21 +95,21 @@ resource "aws_db_instance" "bar" { data "aws_db_instance" "bar" { db_instance_identifier = aws_db_instance.bar.identifier } -`, rInt) +`, rName) } -func testAccInstanceDataSourceConfig_ec2Classic(rInt int) string { +func testAccInstanceDataSourceConfig_ec2Classic(rName string) string { return acctest.ConfigCompose( acctest.ConfigEC2ClassicRegionProvider(), fmt.Sprintf(` data "aws_rds_orderable_db_instance" "test" { engine = "mysql" - engine_version = "5.6.41" - preferred_instance_classes = ["db.m3.medium", "db.m3.large", "db.r3.large"] + engine_version = "8.0.25" + preferred_instance_classes = ["db.t2.micro", "db.m3.medium", "db.m3.large", "db.r3.large"] } resource "aws_db_instance" "bar" { - identifier = "foobarbaz-test-terraform-%[1]d" + identifier = %[1]q allocated_storage = 10 engine = data.aws_rds_orderable_db_instance.test.engine engine_version = data.aws_rds_orderable_db_instance.test.engine_version @@ -118,12 +119,12 @@ resource "aws_db_instance" "bar" { username = "foo" publicly_accessible = true security_group_names = ["default"] - parameter_group_name = "default.mysql5.6" + parameter_group_name = "default.mysql8.0" skip_final_snapshot = true } data "aws_db_instance" "bar" { db_instance_identifier = aws_db_instance.bar.identifier } -`, rInt)) +`, rName)) } diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index 0b3f177b1d4..63610423e33 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -6319,9 +6319,11 @@ resource "aws_db_instance" "test" { } func testAccInstanceConfig_ReplicateSourceDB_AllocatedStorage(rName string, allocatedStorage int) string { - return acctest.ConfigCompose(testAccInstanceConfig_orderableClassMySQL(), fmt.Sprintf(` + return acctest.ConfigCompose( + testAccInstanceConfig_orderableClassMySQL(), + fmt.Sprintf(` resource "aws_db_instance" "source" { - allocated_storage = 5 + allocated_storage = %[2]d backup_retention_period = 1 engine = data.aws_rds_orderable_db_instance.test.engine identifier = "%[1]s-source" diff --git a/internal/service/rds/option_group_test.go b/internal/service/rds/option_group_test.go index 9b6d461d38d..1789e519b32 100644 --- a/internal/service/rds/option_group_test.go +++ b/internal/service/rds/option_group_test.go @@ -18,7 +18,8 @@ import ( func TestAccRDSOptionGroup_basic(t *testing.T) { var v rds.OptionGroup - rName := fmt.Sprintf("option-group-test-terraform-%s", sdkacctest.RandString(5)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -29,18 +30,18 @@ func TestAccRDSOptionGroup_basic(t *testing.T) { { Config: testAccOptionGroupBasicConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - acctest.MatchResourceAttrRegionalARN("aws_db_option_group.bar", "arn", "rds", regexp.MustCompile(`og:.+`)), - resource.TestCheckResourceAttr("aws_db_option_group.bar", "engine_name", "mysql"), - resource.TestCheckResourceAttr("aws_db_option_group.bar", "major_engine_version", "5.6"), - resource.TestCheckResourceAttr("aws_db_option_group.bar", "name", rName), - resource.TestCheckResourceAttr("aws_db_option_group.bar", "option.#", "0"), - resource.TestCheckResourceAttr("aws_db_option_group.bar", "option_group_description", "Managed by Terraform"), - resource.TestCheckResourceAttr("aws_db_option_group.bar", "tags.%", "0"), + testAccCheckOptionGroupExists(resourceName, &v), + acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "rds", regexp.MustCompile(`og:.+`)), + resource.TestCheckResourceAttr(resourceName, "engine_name", "mysql"), + resource.TestCheckResourceAttr(resourceName, "major_engine_version", "8.0"), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "option.#", "0"), + resource.TestCheckResourceAttr(resourceName, "option_group_description", "Managed by Terraform"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"name_prefix"}, @@ -51,7 +52,8 @@ func TestAccRDSOptionGroup_basic(t *testing.T) { func TestAccRDSOptionGroup_timeoutBlock(t *testing.T) { var v rds.OptionGroup - rName := fmt.Sprintf("option-group-test-terraform-%s", sdkacctest.RandString(5)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -62,13 +64,12 @@ func TestAccRDSOptionGroup_timeoutBlock(t *testing.T) { { Config: testAccOptionGroupBasicTimeoutBlockConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), ), }, { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"name_prefix"}, @@ -90,8 +91,7 @@ func TestAccRDSOptionGroup_namePrefix(t *testing.T) { Config: testAccOptionGroup_namePrefix, Check: resource.ComposeTestCheckFunc( testAccCheckOptionGroupExists("aws_db_option_group.test", &v), - resource.TestMatchResourceAttr( - "aws_db_option_group.test", "name", regexp.MustCompile("^tf-test-")), + resource.TestMatchResourceAttr("aws_db_option_group.test", "name", regexp.MustCompile("^tf-test-")), ), }, { @@ -158,7 +158,8 @@ func TestAccRDSOptionGroup_optionGroupDescription(t *testing.T) { } func TestAccRDSOptionGroup_basicDestroyWithInstance(t *testing.T) { - rName := fmt.Sprintf("option-group-test-terraform-%s", sdkacctest.RandString(5)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -170,7 +171,7 @@ func TestAccRDSOptionGroup_basicDestroyWithInstance(t *testing.T) { Config: testAccOptionGroupBasicDestroyConfig(rName), }, { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"name_prefix"}, @@ -181,7 +182,8 @@ func TestAccRDSOptionGroup_basicDestroyWithInstance(t *testing.T) { func TestAccRDSOptionGroup_Option_optionSettings(t *testing.T) { var v rds.OptionGroup - rName := fmt.Sprintf("option-group-test-terraform-%s", sdkacctest.RandString(5)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -192,18 +194,16 @@ func TestAccRDSOptionGroup_Option_optionSettings(t *testing.T) { { Config: testAccOptionGroupOptionSettings(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "option.#", "1"), - resource.TestCheckTypeSetElemNestedAttrs("aws_db_option_group.bar", "option.*.option_settings.*", map[string]string{ + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "option.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "option.*.option_settings.*", map[string]string{ "value": "UTC", }), ), }, { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, // Ignore option since our current logic skips "unconfigured" default option settings @@ -213,19 +213,17 @@ func TestAccRDSOptionGroup_Option_optionSettings(t *testing.T) { { Config: testAccOptionGroupOptionSettings_update(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "option.#", "1"), - resource.TestCheckTypeSetElemNestedAttrs("aws_db_option_group.bar", "option.*.option_settings.*", map[string]string{ + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "option.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "option.*.option_settings.*", map[string]string{ "value": "US/Pacific", }), ), }, // Ensure we can import non-default value option settings { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"name_prefix"}, @@ -236,7 +234,8 @@ func TestAccRDSOptionGroup_Option_optionSettings(t *testing.T) { func TestAccRDSOptionGroup_OptionOptionSettings_iamRole(t *testing.T) { var v rds.OptionGroup - rName := fmt.Sprintf("option-group-test-terraform-%s", sdkacctest.RandString(5)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -247,16 +246,14 @@ func TestAccRDSOptionGroup_OptionOptionSettings_iamRole(t *testing.T) { { Config: testAccOptionGroupOptionSettingsIAMRole(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "option.#", "1"), + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "option.#", "1"), testAccCheckOptionGroupOptionSettingsIAMRole(&v), ), }, { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"name_prefix"}, @@ -267,7 +264,8 @@ func TestAccRDSOptionGroup_OptionOptionSettings_iamRole(t *testing.T) { func TestAccRDSOptionGroup_sqlServerOptionsUpdate(t *testing.T) { var v rds.OptionGroup - rName := fmt.Sprintf("option-group-test-terraform-%s", sdkacctest.RandString(5)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -278,13 +276,12 @@ func TestAccRDSOptionGroup_sqlServerOptionsUpdate(t *testing.T) { { Config: testAccOptionGroupSQLServerEEOptions(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), ), }, { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"name_prefix"}, @@ -292,11 +289,9 @@ func TestAccRDSOptionGroup_sqlServerOptionsUpdate(t *testing.T) { { Config: testAccOptionGroupSQLServerEEOptions_update(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "option.#", "1"), + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "option.#", "1"), ), }, }, @@ -305,7 +300,8 @@ func TestAccRDSOptionGroup_sqlServerOptionsUpdate(t *testing.T) { func TestAccRDSOptionGroup_oracleOptionsUpdate(t *testing.T) { var v rds.OptionGroup - rName := fmt.Sprintf("option-group-test-terraform-%s", sdkacctest.RandString(5)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -316,16 +312,14 @@ func TestAccRDSOptionGroup_oracleOptionsUpdate(t *testing.T) { { Config: testAccOptionGroupOracleEEOptionSettings(rName, "13.2.0.0.v2"), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "option.#", "1"), + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "option.#", "1"), testAccCheckOptionGroupOptionVersionAttribute(&v, "13.2.0.0.v2"), ), }, { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, // Ignore option since API responds with **** instead of password @@ -334,11 +328,9 @@ func TestAccRDSOptionGroup_oracleOptionsUpdate(t *testing.T) { { Config: testAccOptionGroupOracleEEOptionSettings(rName, "13.3.0.0.v2"), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "option.#", "1"), + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "option.#", "1"), testAccCheckOptionGroupOptionVersionAttribute(&v, "13.3.0.0.v2"), ), }, @@ -384,7 +376,8 @@ func TestAccRDSOptionGroup_OptionOptionSettings_multipleNonDefault(t *testing.T) func TestAccRDSOptionGroup_multipleOptions(t *testing.T) { var v rds.OptionGroup - rName := fmt.Sprintf("option-group-test-terraform-%s", sdkacctest.RandString(5)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -395,15 +388,13 @@ func TestAccRDSOptionGroup_multipleOptions(t *testing.T) { { Config: testAccOptionGroupMultipleOptions(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "option.#", "2"), + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "option.#", "2"), ), }, { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"name_prefix"}, @@ -613,38 +604,38 @@ func testAccCheckOptionGroupDestroy(s *terraform.State) error { return nil } -func testAccOptionGroupBasicTimeoutBlockConfig(r string) string { +func testAccOptionGroupBasicTimeoutBlockConfig(rName string) string { return fmt.Sprintf(` -resource "aws_db_option_group" "bar" { - name = "%s" +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform" engine_name = "mysql" - major_engine_version = "5.6" + major_engine_version = "8.0" timeouts { delete = "10m" } } -`, r) +`, rName) } -func testAccOptionGroupBasicConfig(r string) string { +func testAccOptionGroupBasicConfig(rName string) string { return fmt.Sprintf(` -resource "aws_db_option_group" "bar" { - name = "%s" +resource "aws_db_option_group" "test" { + name = %[1]q engine_name = "mysql" - major_engine_version = "5.6" + major_engine_version = "8.0" } -`, r) +`, rName) } -func testAccOptionGroupBasicDestroyConfig(r string) string { +func testAccOptionGroupBasicDestroyConfig(rName string) string { return fmt.Sprintf(` -resource "aws_db_instance" "bar" { +resource "aws_db_instance" "test" { allocated_storage = 10 - engine = "mysql" - engine_version = "5.6.35" - instance_class = "db.t2.micro" + engine = data.aws_rds_orderable_db_instance.test.engine + engine_version = data.aws_rds_orderable_db_instance.test.engine_version + instance_class = data.aws_rds_orderable_db_instance.test.instance_class name = "baz" password = "barbarbarbar" username = "foo" @@ -657,22 +648,31 @@ resource "aws_db_instance" "bar" { backup_retention_period = 0 skip_final_snapshot = true - option_group_name = aws_db_option_group.bar.name + option_group_name = aws_db_option_group.test.name } -resource "aws_db_option_group" "bar" { - name = "%s" +data "aws_rds_orderable_db_instance" "test" { + engine = "mysql" + license_model = "general-public-license" + storage_type = "standard" + + preferred_engine_versions = ["8.0.25", "8.0.26", "8.0.27"] + preferred_instance_classes = ["db.t2.micro", "db.t2.small", "db.t3.medium", "db.t3.large"] +} + +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform" engine_name = "mysql" - major_engine_version = "5.6" + major_engine_version = "8.0" } -`, r) +`, rName) } -func testAccOptionGroupOptionSettings(r string) string { +func testAccOptionGroupOptionSettings(rName string) string { return fmt.Sprintf(` -resource "aws_db_option_group" "bar" { - name = "%s" +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform" engine_name = "oracle-ee" major_engine_version = "12.2" @@ -686,10 +686,10 @@ resource "aws_db_option_group" "bar" { } } } -`, r) +`, rName) } -func testAccOptionGroupOptionSettingsIAMRole(r string) string { +func testAccOptionGroupOptionSettingsIAMRole(rName string) string { return fmt.Sprintf(` data "aws_partition" "current" {} @@ -709,8 +709,8 @@ resource "aws_iam_role" "sql_server_backup" { assume_role_policy = data.aws_iam_policy_document.rds_assume_role.json } -resource "aws_db_option_group" "bar" { - name = "%[1]s" +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform" engine_name = "sqlserver-ex" major_engine_version = "14.00" @@ -724,13 +724,13 @@ resource "aws_db_option_group" "bar" { } } } -`, r) +`, rName) } -func testAccOptionGroupOptionSettings_update(r string) string { +func testAccOptionGroupOptionSettings_update(rName string) string { return fmt.Sprintf(` -resource "aws_db_option_group" "bar" { - name = "%s" +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform" engine_name = "oracle-ee" major_engine_version = "12.2" @@ -744,24 +744,24 @@ resource "aws_db_option_group" "bar" { } } } -`, r) +`, rName) } -func testAccOptionGroupSQLServerEEOptions(r string) string { +func testAccOptionGroupSQLServerEEOptions(rName string) string { return fmt.Sprintf(` -resource "aws_db_option_group" "bar" { - name = "%s" +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform" engine_name = "sqlserver-ee" major_engine_version = "11.00" } -`, r) +`, rName) } -func testAccOptionGroupSQLServerEEOptions_update(r string) string { +func testAccOptionGroupSQLServerEEOptions_update(rName string) string { return fmt.Sprintf(` -resource "aws_db_option_group" "bar" { - name = "%s" +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform" engine_name = "sqlserver-ee" major_engine_version = "11.00" @@ -770,17 +770,17 @@ resource "aws_db_option_group" "bar" { option_name = "TDE" } } -`, r) +`, rName) } -func testAccOptionGroupOracleEEOptionSettings(r, optionVersion string) string { +func testAccOptionGroupOracleEEOptionSettings(rName, optionVersion string) string { return fmt.Sprintf(` resource "aws_security_group" "foo" { - name = "%[1]s" + name = %[1]q } -resource "aws_db_option_group" "bar" { - name = "%[1]s" +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform issue 748" engine_name = "oracle-ee" major_engine_version = "12.2" @@ -788,7 +788,7 @@ resource "aws_db_option_group" "bar" { option { option_name = "OEM_AGENT" port = "3872" - version = "%[2]s" + version = %[2]q vpc_security_group_memberships = [aws_security_group.foo.id] @@ -808,13 +808,13 @@ resource "aws_db_option_group" "bar" { } } } -`, r, optionVersion) +`, rName, optionVersion) } -func testAccOptionGroupMultipleOptions(r string) string { +func testAccOptionGroupMultipleOptions(rName string) string { return fmt.Sprintf(` -resource "aws_db_option_group" "bar" { - name = "%s" +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform" engine_name = "oracle-ee" major_engine_version = "12.2" @@ -827,7 +827,7 @@ resource "aws_db_option_group" "bar" { option_name = "STATSPACK" } } -`, r) +`, rName) } const testAccOptionGroup_namePrefix = ` @@ -835,7 +835,7 @@ resource "aws_db_option_group" "test" { name_prefix = "tf-test-" option_group_description = "Test option group for terraform" engine_name = "mysql" - major_engine_version = "5.6" + major_engine_version = "8.0" } ` @@ -843,7 +843,7 @@ const testAccOptionGroup_generatedName = ` resource "aws_db_option_group" "test" { option_group_description = "Test option group for terraform" engine_name = "mysql" - major_engine_version = "5.6" + major_engine_version = "8.0" } ` @@ -851,9 +851,9 @@ func testAccOptionGroupOptionGroupDescriptionConfig(rName, optionGroupDescriptio return fmt.Sprintf(` resource "aws_db_option_group" "test" { engine_name = "mysql" - major_engine_version = "5.6" - name = %q - option_group_description = %q + major_engine_version = "8.0" + name = %[1]q + option_group_description = %[2]q } `, rName, optionGroupDescription) } @@ -862,15 +862,15 @@ func testAccOptionGroupOptionOptionSettingsMultipleConfig(rName, value string) s return fmt.Sprintf(` resource "aws_db_option_group" "test" { engine_name = "mysql" - major_engine_version = "5.6" - name = %q + major_engine_version = "8.0" + name = %[1]q option { option_name = "MARIADB_AUDIT_PLUGIN" option_settings { name = "SERVER_AUDIT_EXCL_USERS" - value = %q + value = %[2]q } option_settings { @@ -891,11 +891,11 @@ func testAccOptionGroupTags1Config(rName, tagKey1, tagValue1 string) string { return fmt.Sprintf(` resource "aws_db_option_group" "test" { engine_name = "mysql" - major_engine_version = "5.6" - name = %q + major_engine_version = "8.0" + name = %[1]q tags = { - %q = %q + %[2]q = %[3]q } } `, rName, tagKey1, tagValue1) @@ -905,12 +905,12 @@ func testAccOptionGroupTags2Config(rName, tagKey1, tagValue1, tagKey2, tagValue2 return fmt.Sprintf(` resource "aws_db_option_group" "test" { engine_name = "mysql" - major_engine_version = "5.6" - name = %q + major_engine_version = "8.0" + name = %[1]q tags = { - %q = %q - %q = %q + %[2]q = %[3]q + %[4]q = %[5]q } } `, rName, tagKey1, tagValue1, tagKey2, tagValue2) @@ -920,8 +920,8 @@ func testAccOptionGroupTagsWithOption1Config(rName, tagKey1, tagValue1 string) s return fmt.Sprintf(` resource "aws_db_option_group" "test" { engine_name = "mysql" - major_engine_version = "5.6" - name = %q + major_engine_version = "8.0" + name = %[1]q option { option_name = "MARIADB_AUDIT_PLUGIN" @@ -933,7 +933,7 @@ resource "aws_db_option_group" "test" { } tags = { - %q = %q + %[2]q = %[3]q } } `, rName, tagKey1, tagValue1) @@ -943,8 +943,8 @@ func testAccOptionGroupTagsWithOption2Config(rName, tagKey1, tagValue1, tagKey2, return fmt.Sprintf(` resource "aws_db_option_group" "test" { engine_name = "mysql" - major_engine_version = "5.6" - name = %q + major_engine_version = "8.0" + name = %[1]q option { option_name = "MARIADB_AUDIT_PLUGIN" @@ -956,8 +956,8 @@ resource "aws_db_option_group" "test" { } tags = { - %q = %q - %q = %q + %[2]q = %[3]q + %[4]q = %[5]q } } `, rName, tagKey1, tagValue1, tagKey2, tagValue2) From 8a96c7306993fbeed323301b3032521ec485c306 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Mar 2022 20:15:20 -0500 Subject: [PATCH 113/229] Add constants for instance classes --- internal/service/rds/consts.go | 75 +++++++++++++++++++++++++++++ internal/service/rds/consts_test.go | 12 +++++ 2 files changed, 87 insertions(+) create mode 100644 internal/service/rds/consts.go create mode 100644 internal/service/rds/consts_test.go diff --git a/internal/service/rds/consts.go b/internal/service/rds/consts.go new file mode 100644 index 00000000000..c31b4aa776e --- /dev/null +++ b/internal/service/rds/consts.go @@ -0,0 +1,75 @@ +package rds + +const ( + ClusterRoleStatusActive = "ACTIVE" + ClusterRoleStatusDeleted = "DELETED" + ClusterRoleStatusPending = "PENDING" +) + +const ( + StorageTypeStandard = "standard" + StorageTypeGp2 = "gp2" + StorageTypeIo1 = "io1" +) + +func StorageType_Values() []string { + return []string{ + StorageTypeStandard, + StorageTypeGp2, + StorageTypeIo1, + } +} + +// https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/accessing-monitoring.html#Overview.DBInstance.Status. +const ( + InstanceStatusAvailable = "available" + InstanceStatusBackingUp = "backing-up" + InstanceStatusConfiguringEnhancedMonitoring = "configuring-enhanced-monitoring" + InstanceStatusConfiguringLogExports = "configuring-log-exports" + InstanceStatusCreating = "creating" + InstanceStatusDeleting = "deleting" + InstanceStatusIncompatibleParameters = "incompatible-parameters" + InstanceStatusIncompatibleRestore = "incompatible-restore" + InstanceStatusModifying = "modifying" + InstanceStatusStarting = "starting" + InstanceStatusStopping = "stopping" + InstanceStatusStorageFull = "storage-full" + InstanceStatusStorageOptimization = "storage-optimization" +) + +const ( + EventSubscriptionStatusActive = "active" + EventSubscriptionStatusCreating = "creating" + EventSubscriptionStatusDeleting = "deleting" + EventSubscriptionStatusModifying = "modifying" +) + +const ( + ExportableLogTypeAgent = "agent" + ExportableLogTypeAlert = "alert" + ExportableLogTypeAudit = "audit" + ExportableLogTypeError = "error" + ExportableLogTypeGeneral = "general" + ExportableLogTypeListener = "listener" + ExportableLogTypeOEMAgent = "oemagent" + ExportableLogTypePostgreSQL = "postgresql" + ExportableLogTypeSlowQuery = "slowquery" + ExportableLogTypeTrace = "trace" + ExportableLogTypeUpgrade = "upgrade" +) + +func ExportableLogType_Values() []string { + return []string{ + ExportableLogTypeAgent, + ExportableLogTypeAlert, + ExportableLogTypeAudit, + ExportableLogTypeError, + ExportableLogTypeGeneral, + ExportableLogTypeListener, + ExportableLogTypeOEMAgent, + ExportableLogTypePostgreSQL, + ExportableLogTypeSlowQuery, + ExportableLogTypeTrace, + ExportableLogTypeUpgrade, + } +} diff --git a/internal/service/rds/consts_test.go b/internal/service/rds/consts_test.go new file mode 100644 index 00000000000..b2e22376478 --- /dev/null +++ b/internal/service/rds/consts_test.go @@ -0,0 +1,12 @@ +package rds_test + +const ( + // Please make sure GovCloud and commercial support these since they vary + postgresPreferredInstanceClasses = `"db.t3.micro", "db.t3.small", "db.t2.small", "db.t2.medium"` + mySQLPreferredInstanceClasses = `"db.t3.micro", "db.t3.small", "db.t2.small", "db.t2.medium"` + mariaDBPreferredInstanceClasses = `"db.t3.micro", "db.t3.small", "db.t2.small", "db.t2.medium"` + oraclePreferredInstanceClasses = `"db.t3.medium", "db.t2.medium", "db.t3.large", "db.t2.large"` // Oracle requires at least a medium instance as a replica source + sqlServerPreferredInstanceClasses = `"db.t2.small", "db.t3.small"` + sqlServerSEPreferredInstanceClasses = `"db.m5.large", "db.m4.large", "db.r4.large"` + oracleSE2PreferredInstanceClasses = `"db.m5.large", "db.m4.large", "db.r4.large"` +) From 8f43566a557045c3ee80895e37cc25882ee17d62 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Mar 2022 20:15:49 -0500 Subject: [PATCH 114/229] rds/cluster: Debugging --- internal/service/rds/cluster.go | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/internal/service/rds/cluster.go b/internal/service/rds/cluster.go index d7d9e5874f2..31391e56678 100644 --- a/internal/service/rds/cluster.go +++ b/internal/service/rds/cluster.go @@ -23,9 +23,9 @@ import ( ) const ( - rdsClusterScalingConfiguration_DefaultMinCapacity = 1 - rdsClusterScalingConfiguration_DefaultMaxCapacity = 16 - rdsClusterTimeoutDelete = 2 * time.Minute + clusterScalingConfiguration_DefaultMinCapacity = 1 + clusterScalingConfiguration_DefaultMaxCapacity = 16 + clusterTimeoutDelete = 2 * time.Minute ) func ResourceCluster() *schema.Resource { @@ -205,12 +205,12 @@ func ResourceCluster() *schema.Resource { "max_capacity": { Type: schema.TypeInt, Optional: true, - Default: rdsClusterScalingConfiguration_DefaultMaxCapacity, + Default: clusterScalingConfiguration_DefaultMaxCapacity, }, "min_capacity": { Type: schema.TypeInt, Optional: true, - Default: rdsClusterScalingConfiguration_DefaultMinCapacity, + Default: clusterScalingConfiguration_DefaultMinCapacity, }, "seconds_until_auto_pause": { Type: schema.TypeInt, @@ -1084,7 +1084,7 @@ func resourceClusterRead(d *schema.ResourceData, meta interface{}) error { d.Set("hosted_zone_id", dbc.HostedZoneId) d.Set("iam_database_authentication_enabled", dbc.IAMDatabaseAuthenticationEnabled) - rdsClusterSetResourceDataEngineVersionFromCluster(d, dbc) + clusterSetResourceDataEngineVersionFromCluster(d, dbc) var roles []string for _, r := range dbc.AssociatedRoles { @@ -1401,7 +1401,7 @@ func resourceClusterDelete(d *schema.ResourceData, meta interface{}) error { log.Printf("[DEBUG] RDS Cluster delete options: %s", deleteOpts) - err := resource.Retry(rdsClusterTimeoutDelete, func() *resource.RetryError { + err := resource.Retry(clusterTimeoutDelete, func() *resource.RetryError { _, err := conn.DeleteDBCluster(&deleteOpts) if err != nil { if tfawserr.ErrMessageContains(err, rds.ErrCodeInvalidDBClusterStateFault, "is not currently in the available state") { @@ -1538,25 +1538,8 @@ func WaitForClusterDeletion(conn *rds.RDS, id string, timeout time.Duration) err return err } -func rdsClusterSetResourceDataEngineVersionFromCluster(d *schema.ResourceData, c *rds.DBCluster) { +func clusterSetResourceDataEngineVersionFromCluster(d *schema.ResourceData, c *rds.DBCluster) { oldVersion := d.Get("engine_version").(string) newVersion := aws.StringValue(c.EngineVersion) compareActualEngineVersion(d, oldVersion, newVersion) } - -func compareActualEngineVersion(d *schema.ResourceData, oldVersion string, newVersion string) { - newVersionSubstr := newVersion - - if len(newVersion) > len(oldVersion) { - newVersionSubstr = string([]byte(newVersion)[0 : len(oldVersion)+1]) - } - - if oldVersion != newVersion && string(append([]byte(oldVersion), []byte(".")...)) != newVersionSubstr { - d.Set("engine_version", newVersion) - fmt.Printf("[READ/cluster] engine_version: %s\n", newVersion) - } - - d.Set("engine_version_actual", newVersion) - fmt.Printf("[READ/cluster] engine_version_actual: %s\n", newVersion) - -} From 5071312c5689f609c78234b0ab08f1bb1df2ff59 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Mar 2022 20:16:16 -0500 Subject: [PATCH 115/229] rds/instance: Modernize tests --- internal/service/rds/instance_test.go | 696 +++++++++++++------------- 1 file changed, 349 insertions(+), 347 deletions(-) diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index 63610423e33..7c3ac2a553f 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -173,7 +173,7 @@ func TestAccRDSInstance_onlyMajorVersion(t *testing.T) { CheckDestroy: testAccCheckClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_MajorVersionOnly(engine, engineVersion), + Config: testAccInstanceConfig_MajorVersionOnly(), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &dbInstance1), resource.TestCheckResourceAttr(resourceName, "engine", engine), @@ -260,6 +260,7 @@ func TestAccRDSInstance_kmsKey(t *testing.T) { var v rds.DBInstance kmsKeyResourceName := "aws_kms_key.foo" resourceName := "aws_db_instance.bar" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -268,7 +269,7 @@ func TestAccRDSInstance_kmsKey(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_KMSKeyID(sdkacctest.RandInt()), + Config: testAccInstanceConfig_KMSKeyID(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &v), testAccCheckInstanceAttributes(&v), @@ -293,7 +294,7 @@ func TestAccRDSInstance_kmsKey(t *testing.T) { func TestAccRDSInstance_subnetGroup(t *testing.T) { var v rds.DBInstance - rName := sdkacctest.RandString(10) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -324,7 +325,7 @@ func TestAccRDSInstance_subnetGroup(t *testing.T) { func TestAccRDSInstance_optionGroup(t *testing.T) { var v rds.DBInstance - rName := fmt.Sprintf("tf-option-test-%d", sdkacctest.RandInt()) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -347,6 +348,7 @@ func TestAccRDSInstance_optionGroup(t *testing.T) { func TestAccRDSInstance_iamAuth(t *testing.T) { var v rds.DBInstance + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -355,7 +357,7 @@ func TestAccRDSInstance_iamAuth(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_IAMAuth(sdkacctest.RandInt()), + Config: testAccInstanceConfig_IAMAuth(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_db_instance.bar", &v), testAccCheckInstanceAttributes(&v), @@ -536,7 +538,7 @@ func TestAccRDSInstance_deletionProtection(t *testing.T) { func TestAccRDSInstance_finalSnapshotIdentifier(t *testing.T) { var snap rds.DBInstance - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -547,7 +549,7 @@ func TestAccRDSInstance_finalSnapshotIdentifier(t *testing.T) { CheckDestroy: testAccCheckInstanceSnapshot, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_FinalSnapshotIdentifier(rInt), + Config: testAccInstanceConfig_FinalSnapshotIdentifier(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_db_instance.snapshot", &snap), ), @@ -558,6 +560,7 @@ func TestAccRDSInstance_finalSnapshotIdentifier(t *testing.T) { func TestAccRDSInstance_FinalSnapshotIdentifier_skipFinalSnapshot(t *testing.T) { var snap rds.DBInstance + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -566,7 +569,7 @@ func TestAccRDSInstance_FinalSnapshotIdentifier_skipFinalSnapshot(t *testing.T) CheckDestroy: testAccCheckInstanceNoSnapshot, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_FinalSnapshotIdentifier_SkipFinalSnapshot(), + Config: testAccInstanceConfig_FinalSnapshotIdentifier_SkipFinalSnapshot(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_db_instance.snapshot", &snap), ), @@ -1571,8 +1574,7 @@ func TestAccRDSInstance_ReplicateSourceDB_parameterGroupTwoStep(t *testing.T) { func TestAccRDSInstance_s3Import_basic(t *testing.T) { var snap rds.DBInstance - bucket := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - uniqueId := sdkacctest.RandomWithPrefix("tf-acc-s3-import-test") + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) bucketPrefix := sdkacctest.RandString(5) const resourceName = "aws_db_instance.test" @@ -1584,10 +1586,10 @@ func TestAccRDSInstance_s3Import_basic(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_S3Import_basic(bucket, bucketPrefix, uniqueId), + Config: testAccInstanceConfig_S3Import_basic(rName, bucketPrefix), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &snap), - resource.TestCheckResourceAttr(resourceName, "identifier", uniqueId), + resource.TestCheckResourceAttr(resourceName, "identifier", rName), resource.TestCheckResourceAttr(resourceName, "identifier_prefix", ""), ), }, @@ -1605,8 +1607,7 @@ func TestAccRDSInstance_s3Import_basic(t *testing.T) { func TestAccRDSInstance_s3Import_NameDeprecated_basic(t *testing.T) { var snap rds.DBInstance - bucket := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - uniqueId := sdkacctest.RandomWithPrefix("tf-acc-s3-import-test") + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) bucketPrefix := sdkacctest.RandString(5) const resourceName = "aws_db_instance.test" @@ -1618,10 +1619,10 @@ func TestAccRDSInstance_s3Import_NameDeprecated_basic(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_S3Import_NameDeprecated_basic(bucket, bucketPrefix, uniqueId), + Config: testAccInstanceConfig_S3Import_NameDeprecated_basic(rName, bucketPrefix), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &snap), - resource.TestCheckResourceAttr(resourceName, "identifier", uniqueId), + resource.TestCheckResourceAttr(resourceName, "identifier", rName), resource.TestCheckResourceAttr(resourceName, "identifier_prefix", ""), ), }, @@ -1640,7 +1641,7 @@ func TestAccRDSInstance_s3Import_NameDeprecated_basic(t *testing.T) { func TestAccRDSInstance_s3Import_namePrefix(t *testing.T) { var snap rds.DBInstance const identifierPrefix = "tf-acc-test-prefix-" - bucket := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) bucketPrefix := sdkacctest.RandString(5) const resourceName = "aws_db_instance.test" @@ -1652,7 +1653,7 @@ func TestAccRDSInstance_s3Import_namePrefix(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_S3Import_namePrefix(bucket, bucketPrefix, identifierPrefix), + Config: testAccInstanceConfig_S3Import_namePrefix(rName, bucketPrefix, identifierPrefix), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &snap), create.TestCheckResourceAttrNameFromPrefix(resourceName, "identifier", identifierPrefix), @@ -1673,7 +1674,7 @@ func TestAccRDSInstance_s3Import_namePrefix(t *testing.T) { func TestAccRDSInstance_s3Import_nameGenerated(t *testing.T) { var snap rds.DBInstance - bucket := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) bucketPrefix := sdkacctest.RandString(5) const resourceName = "aws_db_instance.test" @@ -1685,7 +1686,7 @@ func TestAccRDSInstance_s3Import_nameGenerated(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_S3Import_nameGenerated(bucket, bucketPrefix), + Config: testAccInstanceConfig_S3Import_nameGenerated(rName, bucketPrefix), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &snap), create.TestCheckResourceAttrNameGenerated(resourceName, "identifier"), @@ -2729,7 +2730,7 @@ func TestAccRDSInstance_MonitoringRoleARN_removedToEnabled(t *testing.T) { func TestAccRDSInstance_separateIopsUpdate(t *testing.T) { var v rds.DBInstance - rName := sdkacctest.RandString(5) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2759,7 +2760,7 @@ func TestAccRDSInstance_separateIopsUpdate(t *testing.T) { func TestAccRDSInstance_portUpdate(t *testing.T) { var v rds.DBInstance - rName := sdkacctest.RandString(5) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2768,7 +2769,7 @@ func TestAccRDSInstance_portUpdate(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_SnapshotInstanceConfig_mysqlPort(rName), + Config: testAccInstanceConfig_SnapshotInstanceConfig_mySQLPort(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_db_instance.bar", &v), resource.TestCheckResourceAttr( @@ -2790,7 +2791,8 @@ func TestAccRDSInstance_portUpdate(t *testing.T) { func TestAccRDSInstance_MSSQL_tz(t *testing.T) { var v rds.DBInstance - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2799,26 +2801,22 @@ func TestAccRDSInstance_MSSQL_tz(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_MSSQL_timezone(rInt), + Config: testAccInstanceConfig_MSSQL_timezone(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists("aws_db_instance.mssql", &v), + testAccCheckInstanceExists(resourceName, &v), testAccCheckInstanceAttributes_MSSQL(&v, ""), - resource.TestCheckResourceAttr( - "aws_db_instance.mssql", "allocated_storage", "20"), - resource.TestCheckResourceAttr( - "aws_db_instance.mssql", "engine", "sqlserver-ex"), + resource.TestCheckResourceAttr(resourceName, "allocated_storage", "20"), + resource.TestCheckResourceAttr(resourceName, "engine", "sqlserver-ex"), ), }, { - Config: testAccInstanceConfig_MSSQL_timezone_AKST(rInt), + Config: testAccInstanceConfig_MSSQL_timezone_AKST(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists("aws_db_instance.mssql", &v), + testAccCheckInstanceExists(resourceName, &v), testAccCheckInstanceAttributes_MSSQL(&v, "Alaskan Standard Time"), - resource.TestCheckResourceAttr( - "aws_db_instance.mssql", "allocated_storage", "20"), - resource.TestCheckResourceAttr( - "aws_db_instance.mssql", "engine", "sqlserver-ex"), + resource.TestCheckResourceAttr(resourceName, "allocated_storage", "20"), + resource.TestCheckResourceAttr(resourceName, "engine", "sqlserver-ex"), ), }, }, @@ -2892,7 +2890,7 @@ func TestAccRDSInstance_MSSQL_domainSnapshotRestore(t *testing.T) { func TestAccRDSInstance_MySQL_snapshotRestoreWithEngineVersion(t *testing.T) { var v, vRestoredInstance rds.DBInstance - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2901,7 +2899,7 @@ func TestAccRDSInstance_MySQL_snapshotRestoreWithEngineVersion(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_MySQLSnapshotRestoreWithEngineVersion(rInt), + Config: testAccInstanceConfig_MySQLSnapshotRestoreWithEngineVersion(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_db_instance.mysql_restore", &vRestoredInstance), testAccCheckInstanceExists("aws_db_instance.mysql", &v), @@ -2915,6 +2913,7 @@ func TestAccRDSInstance_MySQL_snapshotRestoreWithEngineVersion(t *testing.T) { func TestAccRDSInstance_minorVersion(t *testing.T) { var v rds.DBInstance + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2923,7 +2922,7 @@ func TestAccRDSInstance_minorVersion(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_AutoMinorVersion(), + Config: testAccInstanceConfig_AutoMinorVersion(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_db_instance.bar", &v), ), @@ -2934,7 +2933,7 @@ func TestAccRDSInstance_minorVersion(t *testing.T) { func TestAccRDSInstance_ec2Classic(t *testing.T) { var v rds.DBInstance - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_instance.bar" resource.ParallelTest(t, resource.TestCase{ @@ -2944,7 +2943,7 @@ func TestAccRDSInstance_ec2Classic(t *testing.T) { CheckDestroy: testAccCheckInstanceEC2ClassicDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_EC2Classic(rInt), + Config: testAccInstanceConfig_EC2Classic(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceEC2ClassicExists(resourceName, &v), ), @@ -2956,7 +2955,7 @@ func TestAccRDSInstance_ec2Classic(t *testing.T) { func TestAccRDSInstance_cloudWatchLogsExport(t *testing.T) { var v rds.DBInstance - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2965,7 +2964,7 @@ func TestAccRDSInstance_cloudWatchLogsExport(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_CloudWatchLogsExportConfiguration(rInt), + Config: testAccInstanceConfig_CloudWatchLogsExportConfiguration(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_db_instance.bar", &v), ), @@ -2989,7 +2988,7 @@ func TestAccRDSInstance_cloudWatchLogsExport(t *testing.T) { func TestAccRDSInstance_EnabledCloudWatchLogsExports_mySQL(t *testing.T) { var v rds.DBInstance resourceName := "aws_db_instance.bar" - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2998,7 +2997,7 @@ func TestAccRDSInstance_EnabledCloudWatchLogsExports_mySQL(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_CloudWatchLogsExportConfiguration(rInt), + Config: testAccInstanceConfig_CloudWatchLogsExportConfiguration(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &v), resource.TestCheckResourceAttr(resourceName, "enabled_cloudwatch_logs_exports.#", "2"), @@ -3007,7 +3006,7 @@ func TestAccRDSInstance_EnabledCloudWatchLogsExports_mySQL(t *testing.T) { ), }, { - Config: testAccInstanceConfig_CloudWatchLogsExportConfigurationAdd(rInt), + Config: testAccInstanceConfig_CloudWatchLogsExportConfigurationAdd(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &v), resource.TestCheckResourceAttr(resourceName, "enabled_cloudwatch_logs_exports.#", "3"), @@ -3017,7 +3016,7 @@ func TestAccRDSInstance_EnabledCloudWatchLogsExports_mySQL(t *testing.T) { ), }, { - Config: testAccInstanceConfig_CloudWatchLogsExportConfigurationModify(rInt), + Config: testAccInstanceConfig_CloudWatchLogsExportConfigurationModify(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &v), resource.TestCheckResourceAttr(resourceName, "enabled_cloudwatch_logs_exports.#", "3"), @@ -3027,7 +3026,7 @@ func TestAccRDSInstance_EnabledCloudWatchLogsExports_mySQL(t *testing.T) { ), }, { - Config: testAccInstanceConfig_CloudWatchLogsExportConfigurationDelete(rInt), + Config: testAccInstanceConfig_CloudWatchLogsExportConfigurationDelete(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &v), resource.TestCheckResourceAttr(resourceName, "enabled_cloudwatch_logs_exports.#", "0"), @@ -3144,7 +3143,7 @@ func TestAccRDSInstance_EnabledCloudWatchLogsExports_postgresql(t *testing.T) { func TestAccRDSInstance_noDeleteAutomatedBackups(t *testing.T) { var dbInstance rds.DBInstance - rName := sdkacctest.RandomWithPrefix("tf-testacc-nodelautobak") + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_instance.test" resource.ParallelTest(t, resource.TestCase{ @@ -3749,6 +3748,7 @@ func TestAccRDSInstance_RestoreToPointInTime_sourceIdentifier(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance sourceName := "aws_db_instance.test" resourceName := "aws_db_instance.restore" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -3757,7 +3757,7 @@ func TestAccRDSInstance_RestoreToPointInTime_sourceIdentifier(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_RestoreToPointInTime_SourceIdentifier(), + Config: testAccInstanceConfig_RestoreToPointInTime_SourceIdentifier(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(sourceName, &sourceDbInstance), testAccCheckInstanceExists(resourceName, &dbInstance), @@ -3785,6 +3785,7 @@ func TestAccRDSInstance_RestoreToPointInTime_sourceResourceID(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance sourceName := "aws_db_instance.test" resourceName := "aws_db_instance.restore" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -3793,7 +3794,7 @@ func TestAccRDSInstance_RestoreToPointInTime_sourceResourceID(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_RestoreToPointInTime_SourceResourceID(), + Config: testAccInstanceConfig_RestoreToPointInTime_SourceResourceID(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(sourceName, &sourceDbInstance), testAccCheckInstanceExists(resourceName, &dbInstance), @@ -4096,54 +4097,38 @@ func TestAccRDSInstance_license(t *testing.T) { }) } -func testAccInstanceConfig_orderableClass(engine, version, license string) string { +func testAccInstanceConfig_orderableClass(engine, license, storage, classes string) string { return fmt.Sprintf(` -data "aws_rds_orderable_db_instance" "test" { - engine = %[1]q - engine_version = %[2]q - license_model = %[3]q - storage_type = "standard" - - preferred_instance_classes = ["db.t3.micro", "db.t2.micro", "db.t2.medium"] -} -`, engine, version, license) +data "aws_rds_engine_version" "default" { + engine = %[1]q } -func testAccInstanceConfig_orderableClass_SQLServerEx(engine, version, license string) string { - return fmt.Sprintf(` data "aws_rds_orderable_db_instance" "test" { - engine = %[1]q - engine_version = %[2]q - license_model = %[3]q - storage_type = "standard" + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + license_model = %[2]q + storage_type = %[3]q - preferred_instance_classes = ["db.t2.small", "db.t3.small"] + preferred_instance_classes = [%[4]s] } -`, engine, version, license) +`, engine, license, storage, classes) } func testAccInstanceConfig_orderableClassMySQL() string { - return testAccInstanceConfig_orderableClass("mysql", "8.0.23", "general-public-license") + return testAccInstanceConfig_orderableClass("mysql", "general-public-license", "standard", mySQLPreferredInstanceClasses) } func testAccInstanceConfig_orderableClassMariadb() string { - return testAccInstanceConfig_orderableClass("mariadb", "10.5.12", "general-public-license") + return testAccInstanceConfig_orderableClass("mariadb", "general-public-license", "standard", mariaDBPreferredInstanceClasses) } func testAccInstanceConfig_orderableClassSQLServerEx() string { - return testAccInstanceConfig_orderableClass_SQLServerEx("sqlserver-ex", "15.00.4073.23.v1", "license-included") + return testAccInstanceConfig_orderableClass("sqlserver-ex", "license-included", "standard", sqlServerPreferredInstanceClasses) } -const testAccInstanceConfig_orderableClassSQLServerSe = ` -data "aws_rds_orderable_db_instance" "test" { - engine = "sqlserver-se" - engine_version = "15.00.4073.23.v1" - license_model = "license-included" - storage_type = "standard" - - preferred_instance_classes = ["db.m5.large", "db.m4.large", "db.r4.large"] +func testAccInstanceConfig_orderableClassSQLServerSe() string { + return testAccInstanceConfig_orderableClass("sqlserver-se", "license-included", "standard", sqlServerSEPreferredInstanceClasses) } -` func testAccInstanceBasicConfig(rName string) string { return acctest.ConfigCompose( @@ -4156,8 +4141,8 @@ resource "aws_db_instance" "test" { engine = data.aws_rds_orderable_db_instance.test.engine engine_version = data.aws_rds_orderable_db_instance.test.engine_version instance_class = data.aws_rds_orderable_db_instance.test.instance_class - name = "baz" - parameter_group_name = "default.mysql8.0" + db_name = "baz" + parameter_group_name = "default.${data.aws_rds_engine_version.default.parameter_group_family}" password = "barbarbarbar" skip_final_snapshot = true username = "test" @@ -4182,7 +4167,7 @@ resource "aws_db_instance" "test" { engine_version = data.aws_rds_orderable_db_instance.test.engine_version instance_class = data.aws_rds_orderable_db_instance.test.instance_class name = "baz" # deprecated - parameter_group_name = "default.mysql8.0" + parameter_group_name = "default.${data.aws_rds_engine_version.default.parameter_group_family}" password = "barbarbarbar" skip_final_snapshot = true username = "test" @@ -4195,18 +4180,18 @@ resource "aws_db_instance" "test" { `, rName)) } -func testAccInstanceConfig_MajorVersionOnly(engine, engineVersion string) string { +func testAccInstanceConfig_MajorVersionOnly() string { return acctest.ConfigCompose( testAccInstanceConfig_orderableClassMySQL(), fmt.Sprintf(` resource "aws_db_instance" "test" { allocated_storage = 10 backup_retention_period = 0 - engine = data.aws_rds_orderable_db_instance.test.engine - engine_version = %[1]q + engine = data.aws_rds_engine_version.default.engine + engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) instance_class = data.aws_rds_orderable_db_instance.test.instance_class - name = "baz" - parameter_group_name = "default.%[2]s%[1]s" + db_name = "baz" + parameter_group_name = "default.${data.aws_rds_engine_version.default.parameter_group_family}" password = "barbarbarbar" skip_final_snapshot = true username = "foo" @@ -4216,7 +4201,7 @@ resource "aws_db_instance" "test" { # validation error). maintenance_window = "Fri:09:00-Fri:09:30" } -`, engineVersion, engine)) +`)) } func testAccInstanceConfig_namePrefix(identifierPrefix string) string { @@ -4251,10 +4236,10 @@ resource "aws_db_instance" "test" { `) } -func testAccInstanceConfig_KMSKeyID(rInt int) string { +func testAccInstanceConfig_KMSKeyID(rName string) string { return fmt.Sprintf(` resource "aws_kms_key" "foo" { - description = "Terraform acc test %d" + description = %[1]q policy = < Date: Mon, 7 Mar 2022 20:16:48 -0500 Subject: [PATCH 116/229] rds/option_group_test: Make version dynamic --- internal/service/rds/option_group_test.go | 163 +++++++++++++++------- 1 file changed, 116 insertions(+), 47 deletions(-) diff --git a/internal/service/rds/option_group_test.go b/internal/service/rds/option_group_test.go index 1789e519b32..658c29d44b3 100644 --- a/internal/service/rds/option_group_test.go +++ b/internal/service/rds/option_group_test.go @@ -606,11 +606,15 @@ func testAccCheckOptionGroupDestroy(s *terraform.State) error { func testAccOptionGroupBasicTimeoutBlockConfig(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { name = %[1]q option_group_description = "Test option group for terraform" - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) timeouts { delete = "10m" @@ -621,16 +625,30 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupBasicConfig(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { name = %[1]q - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) } `, rName) } func testAccOptionGroupBasicDestroyConfig(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + +data "aws_rds_orderable_db_instance" "test" { + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + preferred_instance_classes = [%[1]s] +} + resource "aws_db_instance" "test" { allocated_storage = 10 engine = data.aws_rds_orderable_db_instance.test.engine @@ -651,31 +669,26 @@ resource "aws_db_instance" "test" { option_group_name = aws_db_option_group.test.name } -data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" - license_model = "general-public-license" - storage_type = "standard" - - preferred_engine_versions = ["8.0.25", "8.0.26", "8.0.27"] - preferred_instance_classes = ["db.t2.micro", "db.t2.small", "db.t3.medium", "db.t3.large"] -} - resource "aws_db_option_group" "test" { - name = %[1]q + name = %[2]q option_group_description = "Test option group for terraform" - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) } -`, rName) +`, mySQLPreferredInstanceClasses, rName) } func testAccOptionGroupOptionSettings(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "oracle-ee" +} + resource "aws_db_option_group" "test" { name = %[1]q option_group_description = "Test option group for terraform" - engine_name = "oracle-ee" - major_engine_version = "12.2" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+", data.aws_rds_engine_version.default.version) option { option_name = "Timezone" @@ -693,6 +706,10 @@ func testAccOptionGroupOptionSettingsIAMRole(rName string) string { return fmt.Sprintf(` data "aws_partition" "current" {} +data "aws_rds_engine_version" "default" { + engine = "sqlserver-ex" +} + data "aws_iam_policy_document" "rds_assume_role" { statement { actions = ["sts:AssumeRole"] @@ -712,8 +729,8 @@ resource "aws_iam_role" "sql_server_backup" { resource "aws_db_option_group" "test" { name = %[1]q option_group_description = "Test option group for terraform" - engine_name = "sqlserver-ex" - major_engine_version = "14.00" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) option { option_name = "SQLSERVER_BACKUP_RESTORE" @@ -729,11 +746,15 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupOptionSettings_update(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "oracle-ee" +} + resource "aws_db_option_group" "test" { name = %[1]q option_group_description = "Test option group for terraform" - engine_name = "oracle-ee" - major_engine_version = "12.2" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+", data.aws_rds_engine_version.default.version) option { option_name = "Timezone" @@ -749,22 +770,30 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupSQLServerEEOptions(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "sqlserver-ee" +} + resource "aws_db_option_group" "test" { name = %[1]q option_group_description = "Test option group for terraform" - engine_name = "sqlserver-ee" - major_engine_version = "11.00" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) } `, rName) } func testAccOptionGroupSQLServerEEOptions_update(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "sqlserver-ee" +} + resource "aws_db_option_group" "test" { name = %[1]q option_group_description = "Test option group for terraform" - engine_name = "sqlserver-ee" - major_engine_version = "11.00" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) option { option_name = "TDE" @@ -775,6 +804,10 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupOracleEEOptionSettings(rName, optionVersion string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "oracle-ee" +} + resource "aws_security_group" "foo" { name = %[1]q } @@ -782,8 +815,8 @@ resource "aws_security_group" "foo" { resource "aws_db_option_group" "test" { name = %[1]q option_group_description = "Test option group for terraform issue 748" - engine_name = "oracle-ee" - major_engine_version = "12.2" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+", data.aws_rds_engine_version.default.version) option { option_name = "OEM_AGENT" @@ -813,11 +846,15 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupMultipleOptions(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "oracle-ee" +} + resource "aws_db_option_group" "test" { name = %[1]q option_group_description = "Test option group for terraform" - engine_name = "oracle-ee" - major_engine_version = "12.2" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+", data.aws_rds_engine_version.default.version) option { option_name = "SPATIAL" @@ -831,27 +868,39 @@ resource "aws_db_option_group" "test" { } const testAccOptionGroup_namePrefix = ` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { name_prefix = "tf-test-" option_group_description = "Test option group for terraform" - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) } ` const testAccOptionGroup_generatedName = ` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { option_group_description = "Test option group for terraform" - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) } ` func testAccOptionGroupOptionGroupDescriptionConfig(rName, optionGroupDescription string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) name = %[1]q option_group_description = %[2]q } @@ -860,9 +909,13 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupOptionOptionSettingsMultipleConfig(rName, value string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) name = %[1]q option { @@ -889,9 +942,13 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupTags1Config(rName, tagKey1, tagValue1 string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) name = %[1]q tags = { @@ -903,9 +960,13 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupTags2Config(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) name = %[1]q tags = { @@ -918,9 +979,13 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupTagsWithOption1Config(rName, tagKey1, tagValue1 string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) name = %[1]q option { @@ -941,9 +1006,13 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupTagsWithOption2Config(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) name = %[1]q option { From 3f97227e2ace78ed1c2dccedad307e473b50860c Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Mar 2022 20:17:20 -0500 Subject: [PATCH 117/229] rds/ds/orderable: Make version dynamic --- .../orderable_instance_data_source_test.go | 189 +++++++++++------- 1 file changed, 120 insertions(+), 69 deletions(-) diff --git a/internal/service/rds/orderable_instance_data_source_test.go b/internal/service/rds/orderable_instance_data_source_test.go index c767a674a51..586dea7dd56 100644 --- a/internal/service/rds/orderable_instance_data_source_test.go +++ b/internal/service/rds/orderable_instance_data_source_test.go @@ -13,9 +13,7 @@ import ( func TestAccRDSOrderableInstanceDataSource_basic(t *testing.T) { dataSourceName := "data.aws_rds_orderable_db_instance.test" - class := "db.t2.small" engine := "mysql" - engineVersion := "5.7.22" licenseModel := "general-public-license" storageType := "standard" @@ -26,13 +24,13 @@ func TestAccRDSOrderableInstanceDataSource_basic(t *testing.T) { CheckDestroy: nil, Steps: []resource.TestStep{ { - Config: testAccOrderableInstanceDataSourceConfig_basic(class, engine, engineVersion, licenseModel, storageType), + Config: testAccOrderableInstanceDataSourceConfig_basic(engine, licenseModel, storageType), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "instance_class", class), resource.TestCheckResourceAttr(dataSourceName, "engine", engine), - resource.TestCheckResourceAttr(dataSourceName, "engine_version", engineVersion), resource.TestCheckResourceAttr(dataSourceName, "license_model", licenseModel), resource.TestCheckResourceAttr(dataSourceName, "storage_type", storageType), + resource.TestCheckResourceAttrPair(dataSourceName, "engine_version", "data.aws_rds_engine_version.default", "version"), + resource.TestCheckResourceAttrPair(dataSourceName, "instance_class", "data.aws_rds_orderable_db_instance.dynamic", "instance_class"), ), }, }, @@ -41,7 +39,7 @@ func TestAccRDSOrderableInstanceDataSource_basic(t *testing.T) { func TestAccRDSOrderableInstanceDataSource_preferredClass(t *testing.T) { dataSourceName := "data.aws_rds_orderable_db_instance.test" - preferredClass := "db.t2.micro" + preferredClass := "db.t3.micro" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccOrderableInstancePreCheck(t) }, @@ -61,7 +59,6 @@ func TestAccRDSOrderableInstanceDataSource_preferredClass(t *testing.T) { func TestAccRDSOrderableInstanceDataSource_preferredVersion(t *testing.T) { dataSourceName := "data.aws_rds_orderable_db_instance.test" - preferredVersion := "5.7.22" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccOrderableInstancePreCheck(t) }, @@ -70,9 +67,9 @@ func TestAccRDSOrderableInstanceDataSource_preferredVersion(t *testing.T) { CheckDestroy: nil, Steps: []resource.TestStep{ { - Config: testAccOrderableInstanceDataSourceConfig_preferredVersion(preferredVersion), + Config: testAccOrderableInstanceDataSourceConfig_preferredVersion(), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "engine_version", preferredVersion), + resource.TestCheckResourceAttrPair(dataSourceName, "engine_version", "data.aws_rds_engine_version.default", "version"), ), }, }, @@ -81,8 +78,6 @@ func TestAccRDSOrderableInstanceDataSource_preferredVersion(t *testing.T) { func TestAccRDSOrderableInstanceDataSource_preferredClassAndVersion(t *testing.T) { dataSourceName := "data.aws_rds_orderable_db_instance.test" - preferredClass := "db.m3.medium" - preferredVersion := "5.7.22" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccOrderableInstancePreCheck(t) }, @@ -91,10 +86,10 @@ func TestAccRDSOrderableInstanceDataSource_preferredClassAndVersion(t *testing.T CheckDestroy: nil, Steps: []resource.TestStep{ { - Config: testAccOrderableInstanceDataSourceConfig_preferredClassAndVersion(preferredClass, preferredVersion), + Config: testAccOrderableInstanceDataSourceConfig_preferredClassAndVersion(), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "instance_class", preferredClass), - resource.TestCheckResourceAttr(dataSourceName, "engine_version", preferredVersion), + resource.TestCheckResourceAttrPair(dataSourceName, "instance_class", "data.aws_rds_orderable_db_instance.dynamic", "instance_class"), + resource.TestCheckResourceAttrPair(dataSourceName, "engine_version", "data.aws_rds_engine_version.default", "version"), ), }, }, @@ -258,161 +253,217 @@ func testAccOrderableInstancePreCheck(t *testing.T) { } } -func testAccOrderableInstanceDataSourceConfig_basic(class, engine, version, license, storage string) string { +func testAccOrderableInstanceDataSourceConfig_basic(engine, license, storage string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = %[1]q +} + +data "aws_rds_orderable_db_instance" "dynamic" { + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + preferred_instance_classes = [%[2]s] +} + data "aws_rds_orderable_db_instance" "test" { - instance_class = %q - engine = %q - engine_version = %q - license_model = %q - storage_type = %q + instance_class = data.aws_rds_orderable_db_instance.dynamic.instance_class + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + license_model = %[3]q + storage_type = %[4]q } -`, class, engine, version, license, storage) +`, engine, mySQLPreferredInstanceClasses, license, storage) } func testAccOrderableInstanceDataSourceConfig_preferredClass(preferredClass string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" - engine_version = "5.7.22" + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version license_model = "general-public-license" preferred_instance_classes = [ "db.xyz.xlarge", - %q, + %[1]q, "db.t3.small", ] } `, preferredClass) } -func testAccOrderableInstanceDataSourceConfig_preferredVersion(preferredVersion string) string { - return fmt.Sprintf(` +func testAccOrderableInstanceDataSourceConfig_preferredVersion() string { + return ` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" + engine = data.aws_rds_engine_version.default.engine license_model = "general-public-license" storage_type = "standard" preferred_engine_versions = [ "18.42.32", - %q, + data.aws_rds_engine_version.default.version, "not.a.version", ] } -`, preferredVersion) +` } -func testAccOrderableInstanceDataSourceConfig_preferredClassAndVersion(preferredClass, preferredVersion string) string { +func testAccOrderableInstanceDataSourceConfig_preferredClassAndVersion() string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + +data "aws_rds_orderable_db_instance" "dynamic" { + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + preferred_instance_classes = [%[1]s] +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" + engine = data.aws_rds_engine_version.default.engine license_model = "general-public-license" preferred_instance_classes = [ "db.xyz.xlarge", - %q, + data.aws_rds_orderable_db_instance.dynamic.instance_class, "db.t3.small", ] preferred_engine_versions = [ "18.42.32", - %q, + data.aws_rds_engine_version.default.version, "not.a.version", ] } -`, preferredClass, preferredVersion) +`, mySQLPreferredInstanceClasses) } func testAccOrderableInstanceDataSourceConfig_supportsEnhancedMonitoring() string { - return ` + return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" + engine = data.aws_rds_engine_version.default.engine license_model = "general-public-license" storage_type = "standard" supports_enhanced_monitoring = true - preferred_engine_versions = ["8.0.25", "8.0.26", "8.0.27"] - preferred_instance_classes = ["db.t2.small", "db.t3.medium", "db.t3.large"] + preferred_engine_versions = ["8.0.25", "8.0.26", data.aws_rds_engine_version.default.version] + preferred_instance_classes = [%[1]s] } -` +`, mySQLPreferredInstanceClasses) } func testAccOrderableInstanceDataSourceConfig_supportsIAMDatabaseAuthentication() string { - return ` + return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" + engine = data.aws_rds_engine_version.default.engine license_model = "general-public-license" storage_type = "standard" supports_iam_database_authentication = true - preferred_engine_versions = ["8.0.25", "8.0.26", "8.0.27"] - preferred_instance_classes = ["db.t2.small", "db.t3.medium", "db.t3.large"] + preferred_engine_versions = ["8.0.25", "8.0.26", data.aws_rds_engine_version.default.version] + preferred_instance_classes = [%[1]s] } -` +`, mySQLPreferredInstanceClasses) } func testAccOrderableInstanceDataSourceConfig_supportsIops() string { - return ` + return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" + engine = data.aws_rds_engine_version.default.engine license_model = "general-public-license" supports_iops = true - preferred_engine_versions = ["8.0.20", "8.0.19", "8.0.17"] - preferred_instance_classes = ["db.t3.small", "db.t2.xlarge", "db.t2.small"] + preferred_engine_versions = ["8.0.20", "8.0.19", data.aws_rds_engine_version.default.version] + preferred_instance_classes = [%[1]s] } -` +`, mySQLPreferredInstanceClasses) } func testAccOrderableInstanceDataSourceConfig_supportsKerberosAuthentication() string { - return ` + return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "postgres" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "postgres" + engine = data.aws_rds_engine_version.default.engine license_model = "postgresql-license" storage_type = "standard" supports_kerberos_authentication = true - preferred_engine_versions = ["12.3", "11.1", "10.13"] - preferred_instance_classes = ["db.m5.xlarge", "db.r5.large", "db.t3.large"] + preferred_engine_versions = ["14.1", "13.5", data.aws_rds_engine_version.default.version] + preferred_instance_classes = [%[1]s] } -` +`, postgresPreferredInstanceClasses) } func testAccOrderableInstanceDataSourceConfig_supportsPerformanceInsights() string { - return ` + return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" + engine = data.aws_rds_engine_version.default.engine license_model = "general-public-license" supports_performance_insights = true - preferred_engine_versions = ["8.0.25", "8.0.26", "8.0.27"] - preferred_instance_classes = ["db.t2.small", "db.t3.medium", "db.t3.large"] + preferred_engine_versions = ["8.0.25", "8.0.26", data.aws_rds_engine_version.default.version] + preferred_instance_classes = [%[1]s] } -` +`, mySQLPreferredInstanceClasses) } func testAccOrderableInstanceDataSourceConfig_supportsStorageAutoScaling() string { - return ` + return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" + engine = data.aws_rds_engine_version.default.engine license_model = "general-public-license" supports_storage_autoscaling = true - preferred_engine_versions = ["8.0.20", "8.0.19", "5.7.30"] - preferred_instance_classes = ["db.t3.medium", "db.t2.large", "db.t3.xlarge"] + preferred_engine_versions = ["8.0.20", "8.0.19", data.aws_rds_engine_version.default.version] + preferred_instance_classes = [%[1]s] } -` +`, mySQLPreferredInstanceClasses) } func testAccOrderableInstanceDataSourceConfig_supportsStorageEncryption() string { - return ` + return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" + engine = data.aws_rds_engine_version.default.engine license_model = "general-public-license" storage_type = "standard" supports_storage_encryption = true - preferred_engine_versions = ["8.0.25", "8.0.26", "8.0.27"] - preferred_instance_classes = ["db.t2.small", "db.t3.medium", "db.t3.large"] + preferred_engine_versions = ["8.0.25", "8.0.26", data.aws_rds_engine_version.default.version] + preferred_instance_classes = [%[1]s] } -` +`, mySQLPreferredInstanceClasses) } From 642520762519697ad921746ac7b4c2034fa6b31a Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Mar 2022 20:18:04 -0500 Subject: [PATCH 118/229] rds/snapshot: Make version dynamic --- .../service/rds/snapshot_data_source_test.go | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/internal/service/rds/snapshot_data_source_test.go b/internal/service/rds/snapshot_data_source_test.go index 98d27324e19..b7f386d9f4d 100644 --- a/internal/service/rds/snapshot_data_source_test.go +++ b/internal/service/rds/snapshot_data_source_test.go @@ -44,11 +44,21 @@ func testAccCheckSnapshotIDDataSource(n string) resource.TestCheckFunc { func testAccCheckSnapshotDataSourceConfig(rInt int) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + +data "aws_rds_orderable_db_instance" "test" { + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + preferred_instance_classes = [%[1]s] +} + resource "aws_db_instance" "bar" { allocated_storage = 10 - engine = "mysql" - engine_version = "5.6.35" - instance_class = "db.t2.micro" + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + instance_class = data.aws_rds_orderable_db_instance.test.instance_class name = "baz" password = "barbarbarbar" username = "foo" @@ -61,7 +71,7 @@ resource "aws_db_instance" "bar" { backup_retention_period = 0 - parameter_group_name = "default.mysql5.6" + parameter_group_name = "default.${data.aws_rds_engine_version.default.parameter_group_family}" } data "aws_db_snapshot" "snapshot" { @@ -71,7 +81,7 @@ data "aws_db_snapshot" "snapshot" { resource "aws_db_snapshot" "test" { db_instance_identifier = aws_db_instance.bar.id - db_snapshot_identifier = "testsnapshot%d" + db_snapshot_identifier = "testsnapshot%[2]d" } -`, rInt) +`, mySQLPreferredInstanceClasses, rInt) } From 377d439e27b9a2fe354fa91198f0a23cf5552899 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Mar 2022 20:18:35 -0500 Subject: [PATCH 119/229] snapshot/tests: Dynamic version --- internal/service/rds/enum.go | 75 --------------------------- internal/service/rds/snapshot_test.go | 36 +++++++++---- internal/service/rds/verify.go | 24 +++++++++ 3 files changed, 50 insertions(+), 85 deletions(-) delete mode 100644 internal/service/rds/enum.go create mode 100644 internal/service/rds/verify.go diff --git a/internal/service/rds/enum.go b/internal/service/rds/enum.go deleted file mode 100644 index c31b4aa776e..00000000000 --- a/internal/service/rds/enum.go +++ /dev/null @@ -1,75 +0,0 @@ -package rds - -const ( - ClusterRoleStatusActive = "ACTIVE" - ClusterRoleStatusDeleted = "DELETED" - ClusterRoleStatusPending = "PENDING" -) - -const ( - StorageTypeStandard = "standard" - StorageTypeGp2 = "gp2" - StorageTypeIo1 = "io1" -) - -func StorageType_Values() []string { - return []string{ - StorageTypeStandard, - StorageTypeGp2, - StorageTypeIo1, - } -} - -// https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/accessing-monitoring.html#Overview.DBInstance.Status. -const ( - InstanceStatusAvailable = "available" - InstanceStatusBackingUp = "backing-up" - InstanceStatusConfiguringEnhancedMonitoring = "configuring-enhanced-monitoring" - InstanceStatusConfiguringLogExports = "configuring-log-exports" - InstanceStatusCreating = "creating" - InstanceStatusDeleting = "deleting" - InstanceStatusIncompatibleParameters = "incompatible-parameters" - InstanceStatusIncompatibleRestore = "incompatible-restore" - InstanceStatusModifying = "modifying" - InstanceStatusStarting = "starting" - InstanceStatusStopping = "stopping" - InstanceStatusStorageFull = "storage-full" - InstanceStatusStorageOptimization = "storage-optimization" -) - -const ( - EventSubscriptionStatusActive = "active" - EventSubscriptionStatusCreating = "creating" - EventSubscriptionStatusDeleting = "deleting" - EventSubscriptionStatusModifying = "modifying" -) - -const ( - ExportableLogTypeAgent = "agent" - ExportableLogTypeAlert = "alert" - ExportableLogTypeAudit = "audit" - ExportableLogTypeError = "error" - ExportableLogTypeGeneral = "general" - ExportableLogTypeListener = "listener" - ExportableLogTypeOEMAgent = "oemagent" - ExportableLogTypePostgreSQL = "postgresql" - ExportableLogTypeSlowQuery = "slowquery" - ExportableLogTypeTrace = "trace" - ExportableLogTypeUpgrade = "upgrade" -) - -func ExportableLogType_Values() []string { - return []string{ - ExportableLogTypeAgent, - ExportableLogTypeAlert, - ExportableLogTypeAudit, - ExportableLogTypeError, - ExportableLogTypeGeneral, - ExportableLogTypeListener, - ExportableLogTypeOEMAgent, - ExportableLogTypePostgreSQL, - ExportableLogTypeSlowQuery, - ExportableLogTypeTrace, - ExportableLogTypeUpgrade, - } -} diff --git a/internal/service/rds/snapshot_test.go b/internal/service/rds/snapshot_test.go index 57bcd85a457..7e88039110f 100644 --- a/internal/service/rds/snapshot_test.go +++ b/internal/service/rds/snapshot_test.go @@ -187,33 +187,47 @@ func testAccCheckDbSnapshotDisappears(snapshot *rds.DBSnapshot) resource.TestChe func testAccSnapshotBaseConfig(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + +data "aws_rds_orderable_db_instance" "test" { + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + preferred_instance_classes = ["db.t3.small", "db.t2.small", "db.t2.medium"] +} + resource "aws_db_instance" "test" { allocated_storage = 10 - engine = "mysql" - engine_version = "5.6.35" - instance_class = "db.t2.micro" + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + instance_class = data.aws_rds_orderable_db_instance.test.instance_class name = "baz" identifier = %[1]q password = "barbarbarbar" username = "foo" maintenance_window = "Fri:09:00-Fri:09:30" backup_retention_period = 0 - parameter_group_name = "default.mysql5.6" + parameter_group_name = "default.${data.aws_rds_engine_version.default.parameter_group_family}" skip_final_snapshot = true }`, rName) } func testAccSnapshotConfig(rName string) string { - return testAccSnapshotBaseConfig(rName) + fmt.Sprintf(` + return acctest.ConfigCompose( + testAccSnapshotBaseConfig(rName), + fmt.Sprintf(` resource "aws_db_snapshot" "test" { db_instance_identifier = aws_db_instance.test.id db_snapshot_identifier = %[1]q } -`, rName) +`, rName)) } func testAccSnapshotTags1Config(rName, tag1Key, tag1Value string) string { - return testAccSnapshotBaseConfig(rName) + fmt.Sprintf(` + return acctest.ConfigCompose( + testAccSnapshotBaseConfig(rName), + fmt.Sprintf(` resource "aws_db_snapshot" "test" { db_instance_identifier = aws_db_instance.test.id db_snapshot_identifier = %[1]q @@ -222,11 +236,13 @@ resource "aws_db_snapshot" "test" { %[2]q = %[3]q } } -`, rName, tag1Key, tag1Value) +`, rName, tag1Key, tag1Value)) } func testAccSnapshotTags2Config(rName, tag1Key, tag1Value, tag2Key, tag2Value string) string { - return testAccSnapshotBaseConfig(rName) + fmt.Sprintf(` + return acctest.ConfigCompose( + testAccSnapshotBaseConfig(rName), + fmt.Sprintf(` resource "aws_db_snapshot" "test" { db_instance_identifier = aws_db_instance.test.id db_snapshot_identifier = %[1]q @@ -236,5 +252,5 @@ resource "aws_db_snapshot" "test" { %[4]q = %[5]q } } -`, rName, tag1Key, tag1Value, tag2Key, tag2Value) +`, rName, tag1Key, tag1Value, tag2Key, tag2Value)) } diff --git a/internal/service/rds/verify.go b/internal/service/rds/verify.go new file mode 100644 index 00000000000..11ec581641e --- /dev/null +++ b/internal/service/rds/verify.go @@ -0,0 +1,24 @@ +package rds + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func compareActualEngineVersion(d *schema.ResourceData, oldVersion string, newVersion string) { + newVersionSubstr := newVersion + + if len(newVersion) > len(oldVersion) { + newVersionSubstr = string([]byte(newVersion)[0 : len(oldVersion)+1]) + } + + if oldVersion != newVersion && string(append([]byte(oldVersion), []byte(".")...)) != newVersionSubstr { + d.Set("engine_version", newVersion) + fmt.Printf("[READ/cluster] engine_version: %s\n", newVersion) + } + + d.Set("engine_version_actual", newVersion) + fmt.Printf("[READ/cluster] engine_version_actual: %s\n", newVersion) + +} From 1f748cf39cec833c38e15a1904eefa581d38edc1 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Tue, 8 Mar 2022 15:36:26 -0500 Subject: [PATCH 120/229] Additional test fixes --- internal/service/rds/instance_test.go | 309 ++++++++++++++------------ internal/service/rds/subnet_group.go | 7 +- internal/service/rds/wait.go | 11 +- 3 files changed, 177 insertions(+), 150 deletions(-) diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index 7c3ac2a553f..1238ddde5d0 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -5,6 +5,7 @@ import ( "log" "os" "regexp" + "strings" "testing" "github.com/aws/aws-sdk-go/aws" @@ -62,8 +63,8 @@ func TestAccRDSInstance_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "license_model", "general-public-license"), resource.TestCheckResourceAttrSet(resourceName, "maintenance_window"), resource.TestCheckResourceAttr(resourceName, "max_allocated_storage", "0"), - resource.TestCheckResourceAttr(resourceName, "option_group_name", "default:mysql-8-0"), - resource.TestCheckResourceAttr(resourceName, "parameter_group_name", "default.mysql8.0"), + resource.TestMatchResourceAttr(resourceName, "option_group_name", regexp.MustCompile(`^default:mysql-\d`)), + resource.TestMatchResourceAttr(resourceName, "parameter_group_name", regexp.MustCompile(`^default\.mysql\d`)), resource.TestCheckResourceAttr(resourceName, "port", "3306"), resource.TestCheckResourceAttr(resourceName, "publicly_accessible", "false"), resource.TestCheckResourceAttrSet(resourceName, "resource_id"), @@ -295,6 +296,7 @@ func TestAccRDSInstance_kmsKey(t *testing.T) { func TestAccRDSInstance_subnetGroup(t *testing.T) { var v rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -305,17 +307,15 @@ func TestAccRDSInstance_subnetGroup(t *testing.T) { { Config: testAccInstanceConfig_WithSubnetGroup(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists("aws_db_instance.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "db_subnet_group_name", "foo-"+rName), + testAccCheckInstanceExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "db_subnet_group_name", rName), ), }, { Config: testAccInstanceConfig_WithSubnetGroupUpdated(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists("aws_db_instance.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "db_subnet_group_name", "bar-"+rName), + testAccCheckInstanceExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "db_subnet_group_name", fmt.Sprintf("%s-2", rName)), ), }, }, @@ -326,6 +326,7 @@ func TestAccRDSInstance_optionGroup(t *testing.T) { var v rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -336,10 +337,9 @@ func TestAccRDSInstance_optionGroup(t *testing.T) { { Config: testAccInstanceConfig_WithOptionGroup(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists("aws_db_instance.bar", &v), + testAccCheckInstanceExists(resourceName, &v), testAccCheckInstanceAttributes(&v), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "option_group_name", rName), + resource.TestCheckResourceAttr(resourceName, "option_group_name", rName), ), }, }, @@ -699,7 +699,7 @@ func TestAccRDSInstance_password(t *testing.T) { }) } -func TestAccRDSInstance_replicateSourceDB_basic(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_basic(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -736,7 +736,7 @@ func TestAccRDSInstance_replicateSourceDB_basic(t *testing.T) { }) } -func TestAccRDSInstance_replicateSourceDB_namePrefix(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_namePrefix(t *testing.T) { var v rds.DBInstance sourceName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -769,7 +769,7 @@ func TestAccRDSInstance_replicateSourceDB_namePrefix(t *testing.T) { }) } -func TestAccRDSInstance_replicateSourceDB_nameGenerated(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_nameGenerated(t *testing.T) { var v rds.DBInstance sourceName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -801,7 +801,7 @@ func TestAccRDSInstance_replicateSourceDB_nameGenerated(t *testing.T) { }) } -func TestAccRDSInstance_replicateSourceDB_addLater(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_addLater(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1310,7 +1310,7 @@ func TestAccRDSInstance_ReplicateSourceDB_multiAZ(t *testing.T) { }) } -func TestAccRDSInstance_ReplicateSourceDB_parameterGroupName_sameSetOnBoth(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_parameterGroupNameSameSetOnBoth(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1339,7 +1339,7 @@ func TestAccRDSInstance_ReplicateSourceDB_parameterGroupName_sameSetOnBoth(t *te }) } -func TestAccRDSInstance_ReplicateSourceDB_parameterGroupName_differentSetOnBoth(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_parameterGroupNameDifferentSetOnBoth(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1368,7 +1368,7 @@ func TestAccRDSInstance_ReplicateSourceDB_parameterGroupName_differentSetOnBoth( }) } -func TestAccRDSInstance_ReplicateSourceDB_parameterGroupName_replicaCopiesValue(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_parameterGroupNameReplicaCopiesValue(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1396,7 +1396,7 @@ func TestAccRDSInstance_ReplicateSourceDB_parameterGroupName_replicaCopiesValue( }) } -func TestAccRDSInstance_ReplicateSourceDB_parameterGroupName_setOnReplica(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_parameterGroupNameSetOnReplica(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1572,7 +1572,7 @@ func TestAccRDSInstance_ReplicateSourceDB_parameterGroupTwoStep(t *testing.T) { }) } -func TestAccRDSInstance_s3Import_basic(t *testing.T) { +func TestAccRDSInstance_S3Import_basic(t *testing.T) { var snap rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) bucketPrefix := sdkacctest.RandString(5) @@ -1605,7 +1605,7 @@ func TestAccRDSInstance_s3Import_basic(t *testing.T) { }) } -func TestAccRDSInstance_s3Import_NameDeprecated_basic(t *testing.T) { +func TestAccRDSInstance_S3Import_nameDeprecated(t *testing.T) { var snap rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) bucketPrefix := sdkacctest.RandString(5) @@ -1638,7 +1638,7 @@ func TestAccRDSInstance_s3Import_NameDeprecated_basic(t *testing.T) { }) } -func TestAccRDSInstance_s3Import_namePrefix(t *testing.T) { +func TestAccRDSInstance_S3Import_namePrefix(t *testing.T) { var snap rds.DBInstance const identifierPrefix = "tf-acc-test-prefix-" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1672,7 +1672,7 @@ func TestAccRDSInstance_s3Import_namePrefix(t *testing.T) { }) } -func TestAccRDSInstance_s3Import_nameGenerated(t *testing.T) { +func TestAccRDSInstance_S3Import_nameGenerated(t *testing.T) { var snap rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) bucketPrefix := sdkacctest.RandString(5) @@ -1983,7 +1983,7 @@ func TestAccRDSInstance_SnapshotIdentifier_availabilityZone(t *testing.T) { }) } -func TestAccRDSInstance_SnapshotIdentifier_backupRetentionPeriod_override(t *testing.T) { +func TestAccRDSInstance_SnapshotIdentifier_backupRetentionPeriodOverride(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2011,7 +2011,7 @@ func TestAccRDSInstance_SnapshotIdentifier_backupRetentionPeriod_override(t *tes }) } -func TestAccRDSInstance_SnapshotIdentifier_backupRetentionPeriod_unset(t *testing.T) { +func TestAccRDSInstance_SnapshotIdentifier_backupRetentionPeriodUnset(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2098,7 +2098,7 @@ func TestAccRDSInstance_SnapshotIdentifier_dbSubnetGroupName(t *testing.T) { }) } -func TestAccRDSInstance_SnapshotIdentifier_DBSubnetGroupName_ramShared(t *testing.T) { +func TestAccRDSInstance_SnapshotIdentifier_dbSubnetGroupNameRAMShared(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot var dbSubnetGroup rds.DBSubnetGroup @@ -2134,7 +2134,7 @@ func TestAccRDSInstance_SnapshotIdentifier_DBSubnetGroupName_ramShared(t *testin }) } -func TestAccRDSInstance_SnapshotIdentifier_DBSubnetGroupName_vpcSecurityGroupIDs(t *testing.T) { +func TestAccRDSInstance_SnapshotIdentifier_dbSubnetGroupNameVPCSecurityGroupIDs(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot var dbSubnetGroup rds.DBSubnetGroup @@ -2343,7 +2343,7 @@ func TestAccRDSInstance_SnapshotIdentifier_multiAZ(t *testing.T) { }) } -func TestAccRDSInstance_SnapshotIdentifier_multiAZ_sqlServer(t *testing.T) { +func TestAccRDSInstance_SnapshotIdentifier_multiAZSQLServer(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2457,8 +2457,8 @@ func TestAccRDSInstance_SnapshotIdentifier_tags(t *testing.T) { }) } -func TestAccRDSInstance_SnapshotIdentifier_Tags_Clear(t *testing.T) { - acctest.Skip(t, "To be fixed: https://github.com/hashicorp/terraform-provider-aws/issues/5959") +func TestAccRDSInstance_SnapshotIdentifier_tagsRemove(t *testing.T) { + //acctest.Skip(t, "To be fixed: https://github.com/hashicorp/terraform-provider-aws/issues/5959") // --- FAIL: TestAccRDSInstance_SnapshotIdentifierTags_unset (1086.15s) // testing.go:527: Step 0 error: Check failed: Check 4/4 error: aws_db_instance.test: Attribute 'tags.%' expected "0", got "1" @@ -2520,7 +2520,7 @@ func TestAccRDSInstance_SnapshotIdentifier_vpcSecurityGroupIDs(t *testing.T) { // This acceptance test explicitly tests when snapshot_identifier is set, // vpc_security_group_ids is set (which triggered the resource update function), // and tags is set which was missing its ARN used for tagging -func TestAccRDSInstance_SnapshotIdentifier_vpcSecurityGroupIDs_tags(t *testing.T) { +func TestAccRDSInstance_SnapshotIdentifier_vpcSecurityGroupIDsTags(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2761,6 +2761,7 @@ func TestAccRDSInstance_portUpdate(t *testing.T) { var v rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2771,18 +2772,16 @@ func TestAccRDSInstance_portUpdate(t *testing.T) { { Config: testAccInstanceConfig_SnapshotInstanceConfig_mySQLPort(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists("aws_db_instance.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "port", "3306"), + testAccCheckInstanceExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "port", "3306"), ), }, { Config: testAccInstanceConfig_SnapshotInstanceConfig_updateMySQLPort(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists("aws_db_instance.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "port", "3305"), + testAccCheckInstanceExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "port", "3305"), ), }, }, @@ -2891,6 +2890,8 @@ func TestAccRDSInstance_MSSQL_domainSnapshotRestore(t *testing.T) { func TestAccRDSInstance_MySQL_snapshotRestoreWithEngineVersion(t *testing.T) { var v, vRestoredInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_instance.test" + restoreResourceName := "aws_db_instance.restore" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2901,10 +2902,11 @@ func TestAccRDSInstance_MySQL_snapshotRestoreWithEngineVersion(t *testing.T) { { Config: testAccInstanceConfig_MySQLSnapshotRestoreWithEngineVersion(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists("aws_db_instance.mysql_restore", &vRestoredInstance), - testAccCheckInstanceExists("aws_db_instance.mysql", &v), - resource.TestCheckResourceAttr("aws_db_instance.mysql", "engine_version", "8.0.23"), - resource.TestCheckResourceAttr("aws_db_instance.mysql_restore", "engine_version", "8.0.25"), + testAccCheckInstanceExists(restoreResourceName, &vRestoredInstance), + testAccCheckInstanceExists(resourceName, &v), + // Hardcoded older version. Will to update when no longer compatible to upgrade from this to the default version. + resource.TestCheckResourceAttr(resourceName, "engine_version", "8.0.25"), + resource.TestCheckResourceAttrPair(restoreResourceName, "engine_version", "data.aws_rds_engine_version.default", "version"), ), }, }, @@ -3334,12 +3336,12 @@ func testAccCheckInstanceSnapshot(s *terraform.State) error { var found bool for _, t := range listTagsOutput.TagList { - if *t.Key == "Name" && *t.Value == "tf-tags-db" { + if aws.StringValue(t.Key) == "Name" && strings.HasPrefix(aws.StringValue(t.Value), acctest.ResourcePrefix) { found = true } } if !found { - return fmt.Errorf("Expected to find tag Name (%s), but wasn't found. Tags: %s", "tf-tags-db", listTagsOutput.TagList) + return fmt.Errorf("Expected to find tag Name with prefix \"%s\", but wasn't found. Tags: %s", acctest.ResourcePrefix, listTagsOutput.TagList) } // end tag search @@ -4327,7 +4329,7 @@ resource "aws_db_option_group" "test" { option_group_description = "Test option group for terraform" } -resource "aws_db_instance" "bar" { +resource "aws_db_instance" "test" { allocated_storage = 10 engine = aws_db_option_group.test.engine_name engine_version = aws_db_option_group.test.major_engine_version @@ -4904,8 +4906,10 @@ resource "aws_db_instance" "bar" { } func testAccInstanceConfig_SnapshotInstanceConfig_mySQLPort(rName string) string { - return acctest.ConfigCompose(testAccInstanceConfig_orderableClassMySQL(), fmt.Sprintf(` -resource "aws_db_instance" "bar" { + return acctest.ConfigCompose( + testAccInstanceConfig_orderableClassMySQL(), + fmt.Sprintf(` +resource "aws_db_instance" "test" { identifier = %[1]q engine = data.aws_rds_orderable_db_instance.test.engine engine_version = data.aws_rds_orderable_db_instance.test.engine_version @@ -4924,8 +4928,10 @@ resource "aws_db_instance" "bar" { } func testAccInstanceConfig_SnapshotInstanceConfig_updateMySQLPort(rName string) string { - return acctest.ConfigCompose(testAccInstanceConfig_orderableClassMySQL(), fmt.Sprintf(` -resource "aws_db_instance" "bar" { + return acctest.ConfigCompose( + testAccInstanceConfig_orderableClassMySQL(), + fmt.Sprintf(` +resource "aws_db_instance" "test" { identifier = %[1]q engine = data.aws_rds_orderable_db_instance.test.engine engine_version = data.aws_rds_orderable_db_instance.test.engine_version @@ -4948,7 +4954,7 @@ func testAccInstanceConfig_WithSubnetGroup(rName string) string { testAccInstanceConfig_orderableClassMySQL(), acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` -resource "aws_vpc" "foo" { +resource "aws_vpc" "test" { cidr_block = "10.1.0.0/16" tags = { @@ -4956,36 +4962,36 @@ resource "aws_vpc" "foo" { } } -resource "aws_subnet" "foo" { +resource "aws_subnet" "test" { cidr_block = "10.1.1.0/24" availability_zone = data.aws_availability_zones.available.names[0] - vpc_id = aws_vpc.foo.id + vpc_id = aws_vpc.test.id tags = { Name = %[1]q } } -resource "aws_subnet" "bar" { +resource "aws_subnet" "test2" { cidr_block = "10.1.2.0/24" availability_zone = data.aws_availability_zones.available.names[1] - vpc_id = aws_vpc.foo.id + vpc_id = aws_vpc.test.id tags = { Name = "%[1]s-2" } } -resource "aws_db_subnet_group" "foo" { +resource "aws_db_subnet_group" "test" { name = %[1]q - subnet_ids = [aws_subnet.foo.id, aws_subnet.bar.id] + subnet_ids = [aws_subnet.test.id, aws_subnet.test2.id] tags = { Name = %[1]q } } -resource "aws_db_instance" "bar" { +resource "aws_db_instance" "test" { identifier = %[1]q engine = data.aws_rds_orderable_db_instance.test.engine engine_version = data.aws_rds_orderable_db_instance.test.engine_version @@ -4994,7 +5000,7 @@ resource "aws_db_instance" "bar" { username = "foo" password = "barbarbar" parameter_group_name = "default.${data.aws_rds_engine_version.default.parameter_group_family}" - db_subnet_group_name = aws_db_subnet_group.foo.name + db_subnet_group_name = aws_db_subnet_group.test.name port = 3305 allocated_storage = 10 skip_final_snapshot = true @@ -5010,7 +5016,7 @@ func testAccInstanceConfig_WithSubnetGroupUpdated(rName string) string { testAccInstanceConfig_orderableClassMySQL(), acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` -resource "aws_vpc" "foo" { +resource "aws_vpc" "test" { cidr_block = "10.1.0.0/16" tags = { @@ -5018,73 +5024,73 @@ resource "aws_vpc" "foo" { } } -resource "aws_vpc" "bar" { - cidr_block = "10.10.0.0/16" +resource "aws_subnet" "test" { + cidr_block = "10.1.1.0/24" + availability_zone = data.aws_availability_zones.available.names[0] + vpc_id = aws_vpc.test.id tags = { Name = %[1]q } } -resource "aws_subnet" "foo" { - cidr_block = "10.1.1.0/24" - availability_zone = data.aws_availability_zones.available.names[0] - vpc_id = aws_vpc.foo.id +resource "aws_subnet" "test2" { + cidr_block = "10.1.2.0/24" + availability_zone = data.aws_availability_zones.available.names[1] + vpc_id = aws_vpc.test.id + + tags = { + Name = "%[1]s-2" + } +} + +resource "aws_db_subnet_group" "test" { + name = %[1]q + subnet_ids = [aws_subnet.test.id, aws_subnet.test2.id] tags = { Name = %[1]q } } -resource "aws_subnet" "bar" { - cidr_block = "10.1.2.0/24" - availability_zone = data.aws_availability_zones.available.names[1] - vpc_id = aws_vpc.foo.id +resource "aws_vpc" "test2" { + cidr_block = "10.10.0.0/16" tags = { Name = "%[1]s-2" } } -resource "aws_subnet" "test" { +resource "aws_subnet" "test3" { cidr_block = "10.10.3.0/24" availability_zone = data.aws_availability_zones.available.names[1] - vpc_id = aws_vpc.bar.id + vpc_id = aws_vpc.test2.id tags = { Name = "%[1]s-3" } } -resource "aws_subnet" "another_test" { +resource "aws_subnet" "test4" { cidr_block = "10.10.4.0/24" availability_zone = data.aws_availability_zones.available.names[0] - vpc_id = aws_vpc.bar.id + vpc_id = aws_vpc.test2.id tags = { Name = "%[1]s-4" } } -resource "aws_db_subnet_group" "foo" { - name = "%[1]s-1" - subnet_ids = [aws_subnet.foo.id, aws_subnet.bar.id] - - tags = { - Name = %[1]q - } -} - -resource "aws_db_subnet_group" "bar" { +resource "aws_db_subnet_group" "test2" { name = "%[1]s-2" - subnet_ids = [aws_subnet.test.id, aws_subnet.another_test.id] + subnet_ids = [aws_subnet.test3.id, aws_subnet.test4.id] tags = { Name = "%[1]s-2" } } -resource "aws_db_instance" "bar" { +resource "aws_db_instance" "test" { identifier = %[1]q engine = data.aws_rds_orderable_db_instance.test.engine engine_version = data.aws_rds_orderable_db_instance.test.engine_version @@ -5093,14 +5099,15 @@ resource "aws_db_instance" "bar" { username = "foo" password = "barbarbar" parameter_group_name = "default.${data.aws_rds_engine_version.default.parameter_group_family}" - db_subnet_group_name = aws_db_subnet_group.bar.name + db_subnet_group_name = aws_db_subnet_group.test2.name port = 3305 allocated_storage = 10 skip_final_snapshot = true backup_retention_period = 0 + apply_immediately = true - apply_immediately = true + depends_on = [aws_db_subnet_group.test] } `, rName)) } @@ -5461,7 +5468,7 @@ func testAccInstanceConfig_MySQLSnapshotRestoreWithEngineVersion(rName string) s testAccInstanceConfig_orderableClassMySQL(), acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` -resource "aws_vpc" "foo" { +resource "aws_vpc" "test" { cidr_block = "10.1.0.0/16" enable_dns_hostnames = true @@ -5470,15 +5477,14 @@ resource "aws_vpc" "foo" { } } -resource "aws_db_subnet_group" "rds_one" { +resource "aws_db_subnet_group" "test" { name = %[1]q - description = "db subnets for rds_one" - - subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] + description = "db subnets" + subnet_ids = [aws_subnet.test.id, aws_subnet.test2.id] } -resource "aws_subnet" "main" { - vpc_id = aws_vpc.foo.id +resource "aws_subnet" "test" { + vpc_id = aws_vpc.test.id availability_zone = data.aws_availability_zones.available.names[0] cidr_block = "10.1.1.0/24" @@ -5487,8 +5493,8 @@ resource "aws_subnet" "main" { } } -resource "aws_subnet" "other" { - vpc_id = aws_vpc.foo.id +resource "aws_subnet" "test2" { + vpc_id = aws_vpc.test.id availability_zone = data.aws_availability_zones.available.names[1] cidr_block = "10.1.2.0/24" @@ -5497,10 +5503,10 @@ resource "aws_subnet" "other" { } } -resource "aws_db_instance" "mysql" { +resource "aws_db_instance" "test" { allocated_storage = 20 - engine = data.aws_rds_orderable_db_instance.test.engine - engine_version = data.aws_rds_orderable_db_instance.test.engine_version + engine = data.aws_rds_engine_version.default.engine + engine_version = "8.0.25" # test is from older to newer version, update when restore from this to current default version is incompatible identifier = %[1]q instance_class = data.aws_rds_orderable_db_instance.test.instance_class password = "password" @@ -5508,45 +5514,42 @@ resource "aws_db_instance" "mysql" { username = "root" } -resource "aws_db_snapshot" "mysql-snap" { - db_instance_identifier = aws_db_instance.mysql.id +resource "aws_db_snapshot" "test" { + db_instance_identifier = aws_db_instance.test.id db_snapshot_identifier = %[1]q } -resource "aws_db_instance" "mysql_restore" { - identifier = "%[1]s-restore" - - db_subnet_group_name = aws_db_subnet_group.rds_one.name - - instance_class = data.aws_rds_orderable_db_instance.test.instance_class +resource "aws_db_instance" "restore" { allocated_storage = 20 - username = "root" - password = "password" - engine = data.aws_rds_orderable_db_instance.test.engine - engine_version = "8.0.25" + apply_immediately = true backup_retention_period = 0 + db_subnet_group_name = aws_db_subnet_group.test.name + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + identifier = "%[1]s-restore" + instance_class = data.aws_rds_orderable_db_instance.test.instance_class + password = "password" skip_final_snapshot = true - snapshot_identifier = aws_db_snapshot.mysql-snap.id - - apply_immediately = true - vpc_security_group_ids = [aws_security_group.rds-mysql.id] + snapshot_identifier = aws_db_snapshot.test.id + username = "root" + vpc_security_group_ids = [aws_security_group.test.id] } -resource "aws_security_group" "rds-mysql" { +resource "aws_security_group" "test" { name = %[1]q description = "TF Testing" - vpc_id = aws_vpc.foo.id + vpc_id = aws_vpc.test.id } -resource "aws_security_group_rule" "rds-mysql-1" { +resource "aws_security_group_rule" "test" { type = "egress" from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] - security_group_id = aws_security_group.rds-mysql.id + security_group_id = aws_security_group.test.id } `, rName)) } @@ -5569,12 +5572,14 @@ resource "aws_db_instance" "test" { } func testAccInstanceConfig_AutoMinorVersion(rName string) string { - return acctest.ConfigCompose(testAccInstanceConfig_orderableClassMySQL(), fmt.Sprintf(` + return acctest.ConfigCompose( + testAccInstanceConfig_orderableClassMySQL(), + fmt.Sprintf(` resource "aws_db_instance" "bar" { identifier = %[1]q allocated_storage = 10 - engine = data.aws_rds_orderable_db_instance.test.engine - engine_version = "8.0" + engine = data.aws_rds_engine_version.default.engine + engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) instance_class = data.aws_rds_orderable_db_instance.test.instance_class db_name = "baz" password = "barbarbarbar" @@ -6591,15 +6596,20 @@ resource "aws_db_subnet_group" "test" { subnet_ids = aws_subnet.test[*].id } +data "aws_rds_engine_version" "default" { + provider = "awsalternate" + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { provider = "awsalternate" - engine = "mysql" - engine_version = "8.0.23" + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version license_model = "general-public-license" storage_type = "standard" - preferred_instance_classes = ["db.t3.micro", "db.t2.micro", "db.t2.medium"] + preferred_instance_classes = [%[2]s] } resource "aws_db_instance" "source" { @@ -6608,7 +6618,7 @@ resource "aws_db_instance" "source" { allocated_storage = 5 backup_retention_period = 1 db_subnet_group_name = aws_db_subnet_group.alternate.name - engine = data.aws_rds_orderable_db_instance.test.engine + engine = data.aws_rds_engine_version.default.engine identifier = "%[1]s-source" instance_class = data.aws_rds_orderable_db_instance.test.instance_class password = "avoid-plaintext-passwords" @@ -6623,7 +6633,7 @@ resource "aws_db_instance" "test" { replicate_source_db = aws_db_instance.source.arn skip_final_snapshot = true } -`, rName)) +`, rName, mySQLPreferredInstanceClasses)) } // When testing needs to distinguish a second region and second account in the same region @@ -6764,15 +6774,20 @@ resource "aws_security_group" "test" { vpc_id = aws_vpc.alternateaccountsameregion.id } +data "aws_rds_engine_version" "default" { + provider = "awssameaccountalternateregion" + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { provider = "awssameaccountalternateregion" - engine = "mysql" - engine_version = "8.0.23" + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version license_model = "general-public-license" storage_type = "standard" - preferred_instance_classes = ["db.t3.micro", "db.t2.micro", "db.t2.medium"] + preferred_instance_classes = [%[2]s] } resource "aws_db_instance" "source" { @@ -6781,7 +6796,8 @@ resource "aws_db_instance" "source" { allocated_storage = 5 backup_retention_period = 1 db_subnet_group_name = aws_db_subnet_group.sameaccountalternateregion.name - engine = data.aws_rds_orderable_db_instance.test.engine + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version identifier = "%[1]s-source" instance_class = data.aws_rds_orderable_db_instance.test.instance_class password = "avoid-plaintext-passwords" @@ -6797,7 +6813,7 @@ resource "aws_db_instance" "test" { skip_final_snapshot = true vpc_security_group_ids = [aws_security_group.test.id] } -`, rName)) +`, rName, mySQLPreferredInstanceClasses)) } func testAccInstanceConfig_ReplicateSourceDB_DbSubnetGroupName_VPCSecurityGroupIDs(rName string) string { @@ -6876,15 +6892,20 @@ resource "aws_db_subnet_group" "test" { subnet_ids = aws_subnet.test[*].id } +data "aws_rds_engine_version" "default" { + provider = "awsalternate" + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { provider = "awsalternate" - engine = "mysql" - engine_version = "8.0.23" + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version license_model = "general-public-license" storage_type = "standard" - preferred_instance_classes = ["db.t3.micro", "db.t2.micro", "db.t2.medium"] + preferred_instance_classes = [%[2]s] } resource "aws_db_instance" "source" { @@ -6909,7 +6930,7 @@ resource "aws_db_instance" "test" { skip_final_snapshot = true vpc_security_group_ids = [aws_security_group.test.id] } -`, rName)) +`, rName, mySQLPreferredInstanceClasses)) } func testAccInstanceConfig_ReplicateSourceDB_DeletionProtection(rName string, deletionProtection bool) string { @@ -7611,9 +7632,9 @@ resource "aws_db_instance" "test" { func testAccInstanceConfig_SnapshotIdentifier_AllowMajorVersionUpgrade(rName string, allowMajorVersionUpgrade bool) string { return fmt.Sprintf(` -data "aws_rds_orderable_db_instance" "postgres10" { +data "aws_rds_orderable_db_instance" "postgres13" { engine = "postgres" - engine_version = "10.1" + engine_version = "13.5" license_model = "postgresql-license" storage_type = "standard" @@ -7622,10 +7643,10 @@ data "aws_rds_orderable_db_instance" "postgres10" { resource "aws_db_instance" "source" { allocated_storage = 5 - engine = data.aws_rds_orderable_db_instance.postgres10.engine - engine_version = data.aws_rds_orderable_db_instance.postgres10.engine_version + engine = data.aws_rds_orderable_db_instance.postgres13.engine + engine_version = data.aws_rds_orderable_db_instance.postgres13.engine_version identifier = "%[1]s-source" - instance_class = data.aws_rds_orderable_db_instance.postgres10.instance_class + instance_class = data.aws_rds_orderable_db_instance.postgres13.instance_class password = "avoid-plaintext-passwords" username = "tfacctest" skip_final_snapshot = true @@ -7636,9 +7657,9 @@ resource "aws_db_snapshot" "test" { db_snapshot_identifier = %[1]q } -data "aws_rds_orderable_db_instance" "postgres11" { +data "aws_rds_orderable_db_instance" "postgres14" { engine = "postgres" - engine_version = "11.1" + engine_version = "14.1" license_model = "postgresql-license" storage_type = "standard" @@ -7647,8 +7668,8 @@ data "aws_rds_orderable_db_instance" "postgres11" { resource "aws_db_instance" "test" { allow_major_version_upgrade = %[2]t - engine = data.aws_rds_orderable_db_instance.postgres11.engine - engine_version = data.aws_rds_orderable_db_instance.postgres11.engine_version + engine = data.aws_rds_orderable_db_instance.postgres14.engine + engine_version = data.aws_rds_orderable_db_instance.postgres14.engine_version identifier = %[1]q instance_class = aws_db_instance.source.instance_class snapshot_identifier = aws_db_snapshot.test.id diff --git a/internal/service/rds/subnet_group.go b/internal/service/rds/subnet_group.go index 47a29fe7fe6..a3c0ba1894e 100644 --- a/internal/service/rds/subnet_group.go +++ b/internal/service/rds/subnet_group.go @@ -222,7 +222,12 @@ func resourceSubnetGroupDelete(d *schema.ResourceData, meta interface{}) error { MinTimeout: 1 * time.Second, } _, err := stateConf.WaitForState() - return err + + if err != nil { + return fmt.Errorf("deleting RDS Subnet Group (%s): %w", d.Id(), err) + } + + return nil } func resourceSubnetGroupDeleteRefreshFunc( diff --git a/internal/service/rds/wait.go b/internal/service/rds/wait.go index a3917df1d14..2edd2eb0326 100644 --- a/internal/service/rds/wait.go +++ b/internal/service/rds/wait.go @@ -161,11 +161,12 @@ func waitDBInstanceDeleted(conn *rds.RDS, id string, timeout time.Duration) (*rd InstanceStatusStorageFull, InstanceStatusStorageOptimization, }, - Target: []string{}, - Refresh: statusDBInstance(conn, id), - Timeout: timeout, - MinTimeout: 10 * time.Second, - Delay: 30 * time.Second, + Target: []string{}, + Refresh: statusDBInstance(conn, id), + Timeout: timeout, + MinTimeout: 10 * time.Second, + Delay: 30 * time.Second, + ContinuousTargetOccurence: 3, } outputRaw, err := stateConf.WaitForState() From b12939f5ff99d6132ad05b7928b0d2a034e392f8 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Tue, 8 Mar 2022 15:37:13 -0500 Subject: [PATCH 121/229] Continue skipping unfixed test --- internal/service/rds/instance_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index 1238ddde5d0..ecbed815231 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -2458,7 +2458,7 @@ func TestAccRDSInstance_SnapshotIdentifier_tags(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_tagsRemove(t *testing.T) { - //acctest.Skip(t, "To be fixed: https://github.com/hashicorp/terraform-provider-aws/issues/5959") + acctest.Skip(t, "To be fixed: https://github.com/hashicorp/terraform-provider-aws/issues/5959") // --- FAIL: TestAccRDSInstance_SnapshotIdentifierTags_unset (1086.15s) // testing.go:527: Step 0 error: Check failed: Check 4/4 error: aws_db_instance.test: Attribute 'tags.%' expected "0", got "1" From d54c884141da1658166f0f8f7313db68d2f61a80 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Tue, 8 Mar 2022 16:27:47 -0500 Subject: [PATCH 122/229] Flint and steel --- internal/service/rds/global_cluster_test.go | 1 - internal/service/rds/instance.go | 9 +++++++-- internal/service/rds/instance_test.go | 16 ++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index 586ffe58f26..ffb72cf43ec 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -602,7 +602,6 @@ resource "aws_rds_cluster" "test" { resource "aws_rds_cluster_instance" "test" { apply_immediately = true cluster_identifier = aws_rds_cluster.test.id - #cluster_identifier = %[3]q engine = %[1]q engine_version = %[2]q identifier = %[3]q diff --git a/internal/service/rds/instance.go b/internal/service/rds/instance.go index c8cfbe783df..a4b4c4c20ed 100644 --- a/internal/service/rds/instance.go +++ b/internal/service/rds/instance.go @@ -1808,7 +1808,7 @@ func resourceInstanceUpdate(d *schema.ResourceData, meta interface{}) error { if requestUpdate { log.Printf("[DEBUG] DB Instance Modification request: %s", req) - err := resource.Retry(tfiam.PropagationTimeout, func() *resource.RetryError { + err := resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { _, err := conn.ModifyDBInstance(req) // Retry for IAM eventual consistency @@ -1816,6 +1816,11 @@ func resourceInstanceUpdate(d *schema.ResourceData, meta interface{}) error { return resource.RetryableError(err) } + // InvalidDBInstanceState: RDS is configuring Enhanced Monitoring or Performance Insights for this DB instance. Try your request later. + if tfawserr.ErrMessageContains(err, rds.ErrCodeInvalidDBInstanceStateFault, "your request later") { + return resource.RetryableError(err) + } + if err != nil { return resource.NonRetryableError(err) } @@ -1828,7 +1833,7 @@ func resourceInstanceUpdate(d *schema.ResourceData, meta interface{}) error { } if err != nil { - return fmt.Errorf("Error modifying DB Instance %s: %w", d.Id(), err) + return fmt.Errorf("modifying DB Instance %s: %w", d.Id(), err) } log.Printf("[DEBUG] Waiting for DB Instance (%s) to be available", d.Id()) diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index ecbed815231..4a37d60c133 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -5480,7 +5480,7 @@ resource "aws_vpc" "test" { resource "aws_db_subnet_group" "test" { name = %[1]q description = "db subnets" - subnet_ids = [aws_subnet.test.id, aws_subnet.test2.id] + subnet_ids = [aws_subnet.test.id, aws_subnet.test2.id] } resource "aws_subnet" "test" { @@ -5606,8 +5606,7 @@ resource "aws_vpc" "foo" { resource "aws_db_subnet_group" "rds_one" { name = %[1]q description = "db subnets for rds_one" - - subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] + subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] } resource "aws_subnet" "main" { @@ -5668,8 +5667,7 @@ resource "aws_vpc" "foo" { resource "aws_db_subnet_group" "rds_one" { name = %[1]q description = "db subnets for rds_one" - - subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] + subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] } resource "aws_subnet" "main" { @@ -5733,8 +5731,7 @@ resource "aws_vpc" "foo" { resource "aws_db_subnet_group" "rds_one" { name = %[1]q description = "db subnets for rds_one" - - subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] + subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] } resource "aws_subnet" "main" { @@ -5798,8 +5795,7 @@ resource "aws_vpc" "foo" { resource "aws_db_subnet_group" "rds_one" { name = %[1]q description = "db subnets for rds_one" - - subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] + subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] } resource "aws_subnet" "main" { @@ -6597,7 +6593,7 @@ resource "aws_db_subnet_group" "test" { } data "aws_rds_engine_version" "default" { - provider = "awsalternate" + provider = "awsalternate" engine = "mysql" } From cb0944d59e2992b63b28ff56d84d39b55188ef90 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Tue, 8 Mar 2022 16:32:21 -0500 Subject: [PATCH 123/229] More flint --- internal/service/rds/cluster.go | 4 ---- internal/service/rds/global_cluster.go | 3 --- internal/service/rds/instance_test.go | 4 ++-- internal/service/rds/verify.go | 5 ----- 4 files changed, 2 insertions(+), 14 deletions(-) diff --git a/internal/service/rds/cluster.go b/internal/service/rds/cluster.go index 31391e56678..4836782c5bd 100644 --- a/internal/service/rds/cluster.go +++ b/internal/service/rds/cluster.go @@ -559,7 +559,6 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { } if attr, ok := d.GetOk("engine_version"); ok { - fmt.Printf("[CREATE/cluster/snapshot_identifier] engine_version: %s\n", attr.(string)) opts.EngineVersion = aws.String(attr.(string)) } @@ -655,7 +654,6 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { } if attr, ok := d.GetOk("engine_version"); ok { - fmt.Printf("[CREATE/cluster/s3_import] engine_version: %s\n", attr.(string)) createOpts.EngineVersion = aws.String(attr.(string)) } @@ -873,7 +871,6 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { } if attr, ok := d.GetOk("engine_version"); ok { - fmt.Printf("[CREATE/cluster/else] engine_version: %s\n", attr.(string)) createOpts.EngineVersion = aws.String(attr.(string)) } @@ -1186,7 +1183,6 @@ func resourceClusterUpdate(d *schema.ResourceData, meta interface{}) error { } if d.HasChange("engine_version") { - fmt.Printf("[UPDATE/cluster] engine_version: %s\n", d.Get("engine_version").(string)) req.EngineVersion = aws.String(d.Get("engine_version").(string)) requestUpdate = true } diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index 674f4e6fa79..28bd6004fec 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -128,7 +128,6 @@ func resourceGlobalClusterCreate(d *schema.ResourceData, meta interface{}) error } if v, ok := d.GetOk("engine_version"); ok { - fmt.Printf("[CREATE/global_cluster] engine_version: %s\n", v.(string)) input.EngineVersion = aws.String(v.(string)) } @@ -193,7 +192,6 @@ func resourceGlobalClusterRead(d *schema.ResourceData, meta interface{}) error { d.Set("deletion_protection", globalCluster.DeletionProtection) d.Set("engine", globalCluster.Engine) d.Set("engine_version", globalCluster.EngineVersion) - fmt.Printf("[READ/global_cluster] engine_verison: %s\n", aws.StringValue(globalCluster.EngineVersion)) d.Set("global_cluster_identifier", globalCluster.GlobalClusterIdentifier) if err := d.Set("global_cluster_members", flattenGlobalClusterMembers(globalCluster.GlobalClusterMembers)); err != nil { @@ -215,7 +213,6 @@ func resourceGlobalClusterUpdate(d *schema.ResourceData, meta interface{}) error } if d.HasChange("engine_version") { - fmt.Printf("[UPDATE/global_cluster] engine_version: %s\n", d.Get("engine_version").(string)) if err := resourceGlobalClusterUpgradeEngineVersion(d, conn); err != nil { return err } diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index 4a37d60c133..ca3b4baaf4b 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -4185,7 +4185,7 @@ resource "aws_db_instance" "test" { func testAccInstanceConfig_MajorVersionOnly() string { return acctest.ConfigCompose( testAccInstanceConfig_orderableClassMySQL(), - fmt.Sprintf(` + ` resource "aws_db_instance" "test" { allocated_storage = 10 backup_retention_period = 0 @@ -4203,7 +4203,7 @@ resource "aws_db_instance" "test" { # validation error). maintenance_window = "Fri:09:00-Fri:09:30" } -`)) +`) } func testAccInstanceConfig_namePrefix(identifierPrefix string) string { diff --git a/internal/service/rds/verify.go b/internal/service/rds/verify.go index 11ec581641e..c7df67724dc 100644 --- a/internal/service/rds/verify.go +++ b/internal/service/rds/verify.go @@ -1,8 +1,6 @@ package rds import ( - "fmt" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -15,10 +13,7 @@ func compareActualEngineVersion(d *schema.ResourceData, oldVersion string, newVe if oldVersion != newVersion && string(append([]byte(oldVersion), []byte(".")...)) != newVersionSubstr { d.Set("engine_version", newVersion) - fmt.Printf("[READ/cluster] engine_version: %s\n", newVersion) } d.Set("engine_version_actual", newVersion) - fmt.Printf("[READ/cluster] engine_version_actual: %s\n", newVersion) - } From c587562753569df2c10d95e9d65f35cd5c8fbef8 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Thu, 10 Mar 2022 17:49:26 -0500 Subject: [PATCH 124/229] Fix additional tests --- internal/service/rds/cluster_instance_test.go | 6 +- internal/service/rds/cluster_test.go | 48 +++++--- .../rds/engine_version_data_source_test.go | 12 +- internal/service/rds/event_subscription.go | 4 +- internal/service/rds/global_cluster.go | 4 + internal/service/rds/global_cluster_test.go | 79 +++++++----- .../service/rds/instance_data_source_test.go | 113 +++++++++++------- internal/service/rds/wait.go | 13 +- 8 files changed, 171 insertions(+), 108 deletions(-) diff --git a/internal/service/rds/cluster_instance_test.go b/internal/service/rds/cluster_instance_test.go index 649138ddf61..d688a4a6f6d 100644 --- a/internal/service/rds/cluster_instance_test.go +++ b/internal/service/rds/cluster_instance_test.go @@ -656,7 +656,7 @@ func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyIDAuroraMySQL1_defaultKe }, { Config: testAccClusterInstancePerformanceInsightsKMSKeyIdAuroraMySQL1Config(rName, engine), - ExpectError: regexp.MustCompile(`InvalidParameterCombination: You cannot change your Performance Insights KMS key`), + ExpectError: regexp.MustCompile(`InvalidParameterCombination: You .* change your Performance Insights KMS key`), }, }, }) @@ -728,7 +728,7 @@ func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyIDAuroraMySQL2_defaultKe }, { Config: testAccClusterInstancePerformanceInsightsKMSKeyIdAuroraMySQL2Config(rName, engine, engineVersion), - ExpectError: regexp.MustCompile(`InvalidParameterCombination: You cannot change your Performance Insights KMS key`), + ExpectError: regexp.MustCompile(`InvalidParameterCombination: You .* change your Performance Insights KMS key`), }, }, }) @@ -838,7 +838,7 @@ func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyIDAuroraPostgresql_defau }, { Config: testAccClusterInstancePerformanceInsightsKMSKeyIdAuroraPostgresqlConfig(rName, engine), - ExpectError: regexp.MustCompile(`InvalidParameterCombination: You cannot change your Performance Insights KMS key`), + ExpectError: regexp.MustCompile(`InvalidParameterCombination: You .* change your Performance Insights KMS key`), }, }, }) diff --git a/internal/service/rds/cluster_test.go b/internal/service/rds/cluster_test.go index 0ac9a15bc8a..d0abe29c25e 100644 --- a/internal/service/rds/cluster_test.go +++ b/internal/service/rds/cluster_test.go @@ -91,8 +91,8 @@ func TestAccRDSCluster_allowMajorVersionUpgrade(t *testing.T) { // either by having a new data source created or implementing the testing similar // to TestAccAWSDmsReplicationInstance_EngineVersion engine := "aurora-postgresql" - engineVersion1 := "10.11" - engineVersion2 := "11.7" + engineVersion1 := "12.9" + engineVersion2 := "13.5" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -144,8 +144,8 @@ func TestAccRDSCluster_allowMajorVersionUpgradeWithCustomParametersApplyImm(t *t // either by having a new data source created or implementing the testing similar // to TestAccAWSDmsReplicationInstance_EngineVersion engine := "aurora-postgresql" - engineVersion1 := "11.9" - engineVersion2 := "12.4" + engineVersion1 := "12.9" + engineVersion2 := "13.5" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -183,8 +183,8 @@ func TestAccRDSCluster_allowMajorVersionUpgradeWithCustomParameters(t *testing.T // either by having a new data source created or implementing the testing similar // to TestAccAWSDmsReplicationInstance_EngineVersion engine := "aurora-postgresql" - engineVersion1 := "10.11" - engineVersion2 := "11.7" + engineVersion1 := "12.9" + engineVersion2 := "13.5" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -1242,7 +1242,7 @@ func TestAccRDSCluster_GlobalClusterIdentifier_secondaryClustersWriteForwarding( func TestAccRDSCluster_port(t *testing.T) { var dbCluster1, dbCluster2 rds.DBCluster - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_cluster.test" resource.ParallelTest(t, resource.TestCase{ @@ -1252,14 +1252,14 @@ func TestAccRDSCluster_port(t *testing.T) { CheckDestroy: testAccCheckClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccClusterConfig_Port(rInt, 5432), + Config: testAccClusterConfig_Port(rName, 5432), Check: resource.ComposeTestCheckFunc( testAccCheckClusterExists(resourceName, &dbCluster1), resource.TestCheckResourceAttr(resourceName, "port", "5432"), ), }, { - Config: testAccClusterConfig_Port(rInt, 2345), + Config: testAccClusterConfig_Port(rName, 2345), Check: resource.ComposeTestCheckFunc( testAccCheckClusterExists(resourceName, &dbCluster2), resource.TestCheckResourceAttr(resourceName, "port", "2345"), @@ -2595,7 +2595,7 @@ func testAccClusterConfig_EngineVersion(upgrade bool, rInt int) string { return fmt.Sprintf(` data "aws_rds_engine_version" "test" { engine = "aurora-postgresql" - preferred_versions = ["9.6.3", "9.6.6", "9.6.8"] + preferred_versions = ["11.6", "11.7", "11.9"] } data "aws_rds_engine_version" "upgrade" { @@ -2666,19 +2666,19 @@ resource "aws_rds_cluster_instance" "test" { `, upgrade, rInt) } -func testAccClusterConfig_Port(rInt, port int) string { +func testAccClusterConfig_Port(rName string, port int) string { return fmt.Sprintf(` resource "aws_rds_cluster" "test" { - cluster_identifier = "tf-acc-test-%d" + cluster_identifier = %[1]q database_name = "mydb" - db_cluster_parameter_group_name = "default.aurora-postgresql11" + db_cluster_parameter_group_name = "default.aurora-postgresql13" engine = "aurora-postgresql" master_password = "mustbeeightcharaters" master_username = "foo" - port = %d + port = %[2]d skip_final_snapshot = true } -`, rInt, port) +`, rName, port) } func testAccClusterIncludingIAMRolesConfig(n int) string { @@ -3182,7 +3182,7 @@ func testAccClusterConfig_GlobalClusterIdentifier_EngineMode_Provisioned(rName s return fmt.Sprintf(` resource "aws_rds_global_cluster" "test" { engine = "aurora-postgresql" - engine_version = "10.11" + engine_version = "12.9" global_cluster_identifier = %[1]q } @@ -3409,10 +3409,20 @@ data "aws_availability_zones" "alternate" { } } +data "aws_rds_engine_version" "default" { + engine = "aurora-postgresql" +} + +data "aws_rds_orderable_db_instance" "test" { + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + preferred_instance_classes = ["db.r5.large", "db.r5.xlarge", "db.r6g.large"] # Aurora global db may be limited to rx +} + resource "aws_rds_global_cluster" "test" { global_cluster_identifier = %[1]q - engine = "aurora-postgresql" - engine_version = "10.11" + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version } resource "aws_rds_cluster" "primary" { @@ -3431,7 +3441,7 @@ resource "aws_rds_cluster_instance" "primary" { engine = aws_rds_cluster.primary.engine engine_version = aws_rds_cluster.primary.engine_version identifier = "%[1]s-primary" - instance_class = "db.r4.large" # only db.r4 or db.r5 are valid for Aurora global db + instance_class = data.aws_rds_orderable_db_instance.test.instance_class } resource "aws_vpc" "alternate" { diff --git a/internal/service/rds/engine_version_data_source_test.go b/internal/service/rds/engine_version_data_source_test.go index 83189f55c7c..26d76153ca6 100644 --- a/internal/service/rds/engine_version_data_source_test.go +++ b/internal/service/rds/engine_version_data_source_test.go @@ -81,7 +81,7 @@ func TestAccRDSEngineVersionDataSource_preferred(t *testing.T) { { Config: testAccEngineVersionPreferredDataSourceConfig(), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "version", "5.7.19"), + resource.TestCheckResourceAttr(dataSourceName, "version", "8.0.27"), ), }, }, @@ -129,9 +129,9 @@ func testAccEngineVersionPreCheck(t *testing.T) { func testAccEngineVersionBasicDataSourceConfig(engine, version, paramGroup string) string { return fmt.Sprintf(` data "aws_rds_engine_version" "test" { - engine = %q - version = %q - parameter_group_family = %q + engine = %[1]q + version = %[2]q + parameter_group_family = %[3]q } `, engine, version, paramGroup) } @@ -140,7 +140,7 @@ func testAccEngineVersionUpgradeTargetsDataSourceConfig() string { return ` data "aws_rds_engine_version" "test" { engine = "mysql" - version = "5.7.17" + version = "8.0.27" } ` } @@ -149,7 +149,7 @@ func testAccEngineVersionPreferredDataSourceConfig() string { return ` data "aws_rds_engine_version" "test" { engine = "mysql" - preferred_versions = ["85.9.12", "5.7.19", "5.7.17"] + preferred_versions = ["85.9.12", "8.0.27", "8.0.26"] } ` } diff --git a/internal/service/rds/event_subscription.go b/internal/service/rds/event_subscription.go index 4b45d79ee36..5b5711d5b5c 100644 --- a/internal/service/rds/event_subscription.go +++ b/internal/service/rds/event_subscription.go @@ -193,9 +193,7 @@ func resourceEventSubscriptionUpdate(d *schema.ResourceData, meta interface{}) e SubscriptionName: aws.String(d.Id()), } - if d.HasChange("enabled") { - input.Enabled = aws.Bool(d.Get("enabled").(bool)) - } + input.Enabled = aws.Bool(d.Get("enabled").(bool)) if d.HasChange("event_categories") { input.EventCategories = flex.ExpandStringSet(d.Get("event_categories").(*schema.Set)) diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index 28bd6004fec..5032a90cb7b 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -563,6 +563,10 @@ func resourceGlobalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, return resource.RetryableError(err) } + if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "Invalid database cluster identifier") { + return resource.RetryableError(err) + } + if tfawserr.ErrMessageContains(err, rds.ErrCodeInvalidDBClusterStateFault, "Cannot modify engine version without a primary instance in DB cluster") { return resource.NonRetryableError(err) } diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index ffb72cf43ec..db9c725e3f0 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -183,10 +183,10 @@ func TestAccRDSGlobalCluster_EngineVersion_aurora(t *testing.T) { CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalClusterEngineVersionConfig(rName, "aurora", "5.6.10a"), + Config: testAccGlobalClusterEngineVersionConfig(rName, "aurora"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.6.10a"), + resource.TestCheckResourceAttrPair(resourceName, "engine_version", "data.aws_rds_engine_version.default", "version"), ), }, { @@ -210,17 +210,17 @@ func TestAccRDSGlobalCluster_engineVersionUpdateMinor(t *testing.T) { CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-mysql", "5.7.mysql_aurora.2.10.1"), + Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-postgresql", "13.4"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), ), }, { - Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-mysql", "5.7.mysql_aurora.2.10.2"), + Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-postgresql", "13.5"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster2), testAccCheckGlobalClusterNotRecreated(&globalCluster1, &globalCluster2), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.7.mysql_aurora.2.10.2"), + resource.TestCheckResourceAttr(resourceName, "engine_version", "13.5"), ), }, { @@ -244,18 +244,17 @@ func TestAccRDSGlobalCluster_engineVersionUpdateMajor(t *testing.T) { CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.7.mysql_aurora.2.10.2"), + Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.6.mysql_aurora.1.23.4"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), ), }, { - Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "8.0.mysql_aurora.3.01.0"), - ExpectNonEmptyPlan: true, + Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-mysql", "5.7.mysql_aurora.2.10.2"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster2), testAccCheckGlobalClusterNotRecreated(&globalCluster1, &globalCluster2), - resource.TestCheckResourceAttr(resourceName, "engine_version", "8.0.mysql_aurora.3.01.0"), + resource.TestCheckResourceAttr(resourceName, "engine_version", "5.7.mysql_aurora.2.10.2"), ), }, { @@ -279,10 +278,10 @@ func TestAccRDSGlobalCluster_EngineVersion_auroraMySQL(t *testing.T) { CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalClusterEngineVersionConfig(rName, "aurora-mysql", "5.7.mysql_aurora.2.07.1"), + Config: testAccGlobalClusterEngineVersionConfig(rName, "aurora-mysql"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.7.mysql_aurora.2.07.1"), + resource.TestCheckResourceAttrPair(resourceName, "engine_version", "data.aws_rds_engine_version.default", "version"), ), }, { @@ -306,10 +305,10 @@ func TestAccRDSGlobalCluster_EngineVersion_auroraPostgresql(t *testing.T) { CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalClusterEngineVersionConfig(rName, "aurora-postgresql", "10.11"), + Config: testAccGlobalClusterEngineVersionConfig(rName, "aurora-postgresql"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), - resource.TestCheckResourceAttr(resourceName, "engine_version", "10.11"), + resource.TestCheckResourceAttrPair(resourceName, "engine_version", "data.aws_rds_engine_version.default", "version"), ), }, { @@ -564,35 +563,47 @@ resource "aws_rds_global_cluster" "test" { `, engine, rName) } -func testAccGlobalClusterEngineVersionConfig(rName, engine, engineVersion string) string { +func testAccGlobalClusterEngineVersionConfig(rName, engine string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = %[1]q +} + resource "aws_rds_global_cluster" "test" { - engine = %[1]q - engine_version = %[2]q - global_cluster_identifier = %[3]q + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + global_cluster_identifier = %[2]q } -`, engine, engineVersion, rName) +`, engine, rName) } func testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, engine, engineVersion string) string { return fmt.Sprintf(` +data "aws_rds_orderable_db_instance" "test" { + engine = %[1]q + engine_version = %[2]q + preferred_instance_classes = ["db.r5.large", "db.r5.xlarge", "db.r6g.large"] # Aurora global db may be limited to rx +} + resource "aws_rds_global_cluster" "test" { - engine = %[1]q - engine_version = %[2]q + engine = data.aws_rds_orderable_db_instance.test.engine + engine_version = data.aws_rds_orderable_db_instance.test.engine_version global_cluster_identifier = %[3]q } +// checkout the newly working global cluster stuff in cluster + resource "aws_rds_cluster" "test" { apply_immediately = true allow_major_version_upgrade = true cluster_identifier = %[3]q - engine = %[1]q - engine_version = %[2]q + engine = data.aws_rds_orderable_db_instance.test.engine + engine_version = data.aws_rds_orderable_db_instance.test.engine_version master_password = "mustbeeightcharacters" master_username = "test" skip_final_snapshot = true - global_cluster_identifier = aws_rds_global_cluster.test.global_cluster_identifier + global_cluster_identifier = aws_rds_global_cluster.test.id lifecycle { ignore_changes = [global_cluster_identifier] @@ -602,10 +613,10 @@ resource "aws_rds_cluster" "test" { resource "aws_rds_cluster_instance" "test" { apply_immediately = true cluster_identifier = aws_rds_cluster.test.id - engine = %[1]q - engine_version = %[2]q + engine = data.aws_rds_orderable_db_instance.test.engine + engine_version = data.aws_rds_orderable_db_instance.test.engine_version identifier = %[3]q - instance_class = "db.r3.large" + instance_class = data.aws_rds_orderable_db_instance.test.instance_class lifecycle { ignore_changes = [engine_version] @@ -616,10 +627,14 @@ resource "aws_rds_cluster_instance" "test" { func testAccGlobalClusterSourceClusterIdentifierConfig(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "aurora-postgresql" +} + resource "aws_rds_cluster" "test" { cluster_identifier = %[1]q - engine = "aurora-postgresql" - engine_version = "10.11" # Minimum supported version for Global Clusters + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version master_password = "mustbeeightcharacters" master_username = "test" skip_final_snapshot = true @@ -641,10 +656,14 @@ resource "aws_rds_global_cluster" "test" { func testAccGlobalClusterSourceClusterIdentifierStorageEncryptedConfig(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "aurora-postgresql" +} + resource "aws_rds_cluster" "test" { cluster_identifier = %[1]q - engine = "aurora-postgresql" - engine_version = "10.11" # Minimum supported version for Global Clusters + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version master_password = "mustbeeightcharacters" master_username = "test" skip_final_snapshot = true diff --git a/internal/service/rds/instance_data_source_test.go b/internal/service/rds/instance_data_source_test.go index 832f18ae86e..bbedf381724 100644 --- a/internal/service/rds/instance_data_source_test.go +++ b/internal/service/rds/instance_data_source_test.go @@ -12,6 +12,7 @@ import ( func TestAccRDSInstanceDataSource_basic(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + dataSourceName := "data.aws_db_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -21,23 +22,23 @@ func TestAccRDSInstanceDataSource_basic(t *testing.T) { { Config: testAccInstanceDataSourceConfig(rName), Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "address"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "allocated_storage"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "auto_minor_version_upgrade"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "db_instance_class"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "db_name"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "db_subnet_group"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "endpoint"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "engine"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "hosted_zone_id"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "master_username"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "port"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "multi_az"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "enabled_cloudwatch_logs_exports.0"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "enabled_cloudwatch_logs_exports.1"), - resource.TestCheckResourceAttrPair("data.aws_db_instance.bar", "resource_id", "aws_db_instance.bar", "resource_id"), - resource.TestCheckResourceAttrPair("data.aws_db_instance.bar", "tags.%", "aws_db_instance.bar", "tags.%"), - resource.TestCheckResourceAttrPair("data.aws_db_instance.bar", "tags.Environment", "aws_db_instance.bar", "tags.Environment"), + resource.TestCheckResourceAttrSet(dataSourceName, "address"), + resource.TestCheckResourceAttrSet(dataSourceName, "allocated_storage"), + resource.TestCheckResourceAttrSet(dataSourceName, "auto_minor_version_upgrade"), + resource.TestCheckResourceAttrSet(dataSourceName, "db_instance_class"), + resource.TestCheckResourceAttrSet(dataSourceName, "db_name"), + resource.TestCheckResourceAttrSet(dataSourceName, "db_subnet_group"), + resource.TestCheckResourceAttrSet(dataSourceName, "endpoint"), + resource.TestCheckResourceAttrSet(dataSourceName, "engine"), + resource.TestCheckResourceAttrSet(dataSourceName, "hosted_zone_id"), + resource.TestCheckResourceAttrSet(dataSourceName, "master_username"), + resource.TestCheckResourceAttrSet(dataSourceName, "port"), + resource.TestCheckResourceAttrSet(dataSourceName, "multi_az"), + resource.TestCheckResourceAttrSet(dataSourceName, "enabled_cloudwatch_logs_exports.0"), + resource.TestCheckResourceAttrSet(dataSourceName, "enabled_cloudwatch_logs_exports.1"), + resource.TestCheckResourceAttrPair(dataSourceName, "resource_id", "aws_db_instance.test", "resource_id"), + resource.TestCheckResourceAttrPair(dataSourceName, "tags.%", "aws_db_instance.test", "tags.%"), + resource.TestCheckResourceAttrPair(dataSourceName, "tags.Environment", "aws_db_instance.test", "tags.Environment"), ), }, }, @@ -46,6 +47,7 @@ func TestAccRDSInstanceDataSource_basic(t *testing.T) { func TestAccRDSInstanceDataSource_ec2Classic(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + dataSourceName := "data.aws_db_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); acctest.PreCheckEC2Classic(t) }, @@ -55,7 +57,7 @@ func TestAccRDSInstanceDataSource_ec2Classic(t *testing.T) { { Config: testAccInstanceDataSourceConfig_ec2Classic(rName), Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("data.aws_db_instance.bar", "db_subnet_group", ""), + resource.TestCheckResourceAttr(dataSourceName, "db_subnet_group", ""), ), }, }, @@ -63,24 +65,47 @@ func TestAccRDSInstanceDataSource_ec2Classic(t *testing.T) { } func testAccInstanceDataSourceConfig(rName string) string { - return fmt.Sprintf(` -data "aws_rds_orderable_db_instance" "test" { - engine = "mariadb" - preferred_instance_classes = ["db.t3.micro", "db.t2.micro", "db.t3.small"] + return acctest.ConfigCompose( + testAccInstanceConfig_orderableClassMariadb(), + acctest.ConfigAvailableAZsNoOptIn(), + fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" + + tags = { + Name = %[1]q + } } -resource "aws_db_instance" "bar" { - identifier = %[1]q +resource "aws_subnet" "test" { + count = 2 - allocated_storage = 10 - engine = data.aws_rds_orderable_db_instance.test.engine - instance_class = data.aws_rds_orderable_db_instance.test.instance_class - name = "baz" - password = "barbarbarbar" - username = "foo" + availability_zone = data.aws_availability_zones.available.names[count.index] + cidr_block = "10.0.${count.index}.0/24" + vpc_id = aws_vpc.test.id + tags = { + Name = %[1]q + } +} + +resource "aws_db_subnet_group" "test" { + name = %[1]q + subnet_ids = aws_subnet.test[*].id +} + +resource "aws_db_instance" "test" { + allocated_storage = 10 backup_retention_period = 0 + db_subnet_group_name = aws_db_subnet_group.test.name + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + identifier = %[1]q + instance_class = data.aws_rds_orderable_db_instance.test.instance_class + name = "baz" + password = "barbarbarbar" skip_final_snapshot = true + username = "foo" enabled_cloudwatch_logs_exports = [ "audit", @@ -92,39 +117,45 @@ resource "aws_db_instance" "bar" { } } -data "aws_db_instance" "bar" { - db_instance_identifier = aws_db_instance.bar.identifier +data "aws_db_instance" "test" { + db_instance_identifier = aws_db_instance.test.identifier } -`, rName) +`, rName)) } func testAccInstanceDataSourceConfig_ec2Classic(rName string) string { return acctest.ConfigCompose( acctest.ConfigEC2ClassicRegionProvider(), fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + +# EC2-Classic specific data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" - engine_version = "8.0.25" - preferred_instance_classes = ["db.t2.micro", "db.m3.medium", "db.m3.large", "db.r3.large"] + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + preferred_instance_classes = ["db.m3.medium", "db.m3.large", "db.r3.large"] } -resource "aws_db_instance" "bar" { +resource "aws_db_instance" "test" { identifier = %[1]q allocated_storage = 10 engine = data.aws_rds_orderable_db_instance.test.engine engine_version = data.aws_rds_orderable_db_instance.test.engine_version instance_class = data.aws_rds_orderable_db_instance.test.instance_class - name = "baz" + storage_type = data.aws_rds_orderable_db_instance.test.storage_type + db_name = "baz" password = "barbarbarbar" username = "foo" publicly_accessible = true security_group_names = ["default"] - parameter_group_name = "default.mysql8.0" + parameter_group_name = "default.${data.aws_rds_engine_version.default.parameter_group_family}" skip_final_snapshot = true } -data "aws_db_instance" "bar" { - db_instance_identifier = aws_db_instance.bar.identifier +data "aws_db_instance" "test" { + db_instance_identifier = aws_db_instance.test.identifier } `, rName)) } diff --git a/internal/service/rds/wait.go b/internal/service/rds/wait.go index 2edd2eb0326..c55a9ac8399 100644 --- a/internal/service/rds/wait.go +++ b/internal/service/rds/wait.go @@ -54,12 +54,13 @@ func waitEventSubscriptionDeleted(conn *rds.RDS, id string, timeout time.Duratio func waitEventSubscriptionUpdated(conn *rds.RDS, id string, timeout time.Duration) (*rds.EventSubscription, error) { stateConf := &resource.StateChangeConf{ - Pending: []string{EventSubscriptionStatusModifying}, - Target: []string{EventSubscriptionStatusActive}, - Refresh: statusEventSubscription(conn, id), - Timeout: timeout, - MinTimeout: 10 * time.Second, - Delay: 30 * time.Second, + Pending: []string{EventSubscriptionStatusModifying}, + Target: []string{EventSubscriptionStatusActive}, + Refresh: statusEventSubscription(conn, id), + Timeout: timeout, + MinTimeout: 10 * time.Second, + Delay: 30 * time.Second, + ContinuousTargetOccurence: 2, } outputRaw, err := stateConf.WaitForState() From 7a2dea79373cda53118a37a88d3abf58ce686266 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Thu, 10 Mar 2022 20:45:22 -0500 Subject: [PATCH 125/229] rds: Fix additional issues --- .changelog/23560.txt | 11 +++ internal/service/rds/cluster.go | 6 +- internal/service/rds/cluster_endpoint.go | 12 +-- internal/service/rds/global_cluster.go | 92 ++++++++++++------- internal/service/rds/global_cluster_test.go | 4 +- internal/service/rds/wait.go | 2 +- .../docs/r/rds_global_cluster.html.markdown | 9 ++ 7 files changed, 92 insertions(+), 44 deletions(-) create mode 100644 .changelog/23560.txt diff --git a/.changelog/23560.txt b/.changelog/23560.txt new file mode 100644 index 00000000000..ad9eaf3f32f --- /dev/null +++ b/.changelog/23560.txt @@ -0,0 +1,11 @@ +```release-note:bug +resource/aws_rds_event_subscription: Fix issue where `enabled` was sometimes not updated +``` + +```release-note:bug +resource/aws_db_instance: Fix issues where configured update timeout was not respected, and update would fail if instance were in the process of being configured. +``` + +```release-note:bug +resource/aws_rds_global_cluster: Fix in-place DB Cluster minor version upgrade error: "Invalid database cluster identifier" +``` \ No newline at end of file diff --git a/internal/service/rds/cluster.go b/internal/service/rds/cluster.go index 4836782c5bd..681a403b00b 100644 --- a/internal/service/rds/cluster.go +++ b/internal/service/rds/cluster.go @@ -990,7 +990,7 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { } log.Printf("[INFO] Waiting for RDS Cluster (%s) to be available", d.Id()) - err = waitForRDSClusterUpdate(conn, d.Id(), d.Timeout(schema.TimeoutCreate)) + err = waitForClusterUpdate(conn, d.Id(), d.Timeout(schema.TimeoutCreate)) if err != nil { return fmt.Errorf("error waiting for RDS Cluster (%s) to be available: %s", d.Id(), err) } @@ -1288,7 +1288,7 @@ func resourceClusterUpdate(d *schema.ResourceData, meta interface{}) error { } log.Printf("[INFO] Waiting for RDS Cluster (%s) to be available", d.Id()) - err = waitForRDSClusterUpdate(conn, d.Id(), d.Timeout(schema.TimeoutUpdate)) + err = waitForClusterUpdate(conn, d.Id(), d.Timeout(schema.TimeoutUpdate)) if err != nil { return fmt.Errorf("error waiting for RDS Cluster (%s) to be available: %s", d.Id(), err) } @@ -1506,7 +1506,7 @@ var resourceClusterUpdatePendingStates = []string{ "upgrading", } -func waitForRDSClusterUpdate(conn *rds.RDS, id string, timeout time.Duration) error { +func waitForClusterUpdate(conn *rds.RDS, id string, timeout time.Duration) error { stateConf := &resource.StateChangeConf{ Pending: resourceClusterUpdatePendingStates, Target: []string{"available"}, diff --git a/internal/service/rds/cluster_endpoint.go b/internal/service/rds/cluster_endpoint.go index 805303b1b1f..bdf9beed532 100644 --- a/internal/service/rds/cluster_endpoint.go +++ b/internal/service/rds/cluster_endpoint.go @@ -18,9 +18,9 @@ import ( ) const ( - AWSRDSClusterEndpointCreateTimeout = 30 * time.Minute - AWSRDSClusterEndpointRetryDelay = 5 * time.Second - ClusterEndpointRetryMinTimeout = 3 * time.Second + clusterEndpointCreateTimeout = 30 * time.Minute + clusterEndpointRetryDelay = 5 * time.Second + ClusterEndpointRetryMinTimeout = 3 * time.Second ) func ResourceClusterEndpoint() *schema.Resource { @@ -114,7 +114,7 @@ func resourceClusterEndpointCreate(d *schema.ResourceData, meta interface{}) err d.SetId(endpointId) - err = resourceClusterEndpointWaitForAvailable(AWSRDSClusterEndpointCreateTimeout, d.Id(), conn) + err = resourceClusterEndpointWaitForAvailable(clusterEndpointCreateTimeout, d.Id(), conn) if err != nil { return err } @@ -252,7 +252,7 @@ func resourceClusterEndpointWaitForDestroy(timeout time.Duration, id string, con Target: []string{"destroyed"}, Refresh: DBClusterEndpointStateRefreshFunc(conn, id), Timeout: timeout, - Delay: AWSRDSClusterEndpointRetryDelay, + Delay: clusterEndpointRetryDelay, MinTimeout: ClusterEndpointRetryMinTimeout, } _, err := stateConf.WaitForState() @@ -270,7 +270,7 @@ func resourceClusterEndpointWaitForAvailable(timeout time.Duration, id string, c Target: []string{"available"}, Refresh: DBClusterEndpointStateRefreshFunc(conn, id), Timeout: timeout, - Delay: AWSRDSClusterEndpointRetryDelay, + Delay: clusterEndpointRetryDelay, MinTimeout: ClusterEndpointRetryMinTimeout, } diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index 5032a90cb7b..994b8f2c46b 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -3,8 +3,10 @@ package rds import ( "fmt" "log" + "strings" "time" + "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/rds" "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" @@ -16,7 +18,9 @@ import ( ) const ( - rdsGlobalClusterRemovalTimeout = 2 * time.Minute + GlobalClusterRemovalTimeout = 30 * time.Minute + globalClusterCreateTimeout = 30 * time.Minute + globalClusterUpdateTimeout = 30 * time.Minute ) func ResourceGlobalCluster() *schema.Resource { @@ -29,6 +33,12 @@ func ResourceGlobalCluster() *schema.Resource { State: schema.ImportStatePassthrough, }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(globalClusterCreateTimeout), + Update: schema.DefaultTimeout(globalClusterUpdateTimeout), + Delete: schema.DefaultTimeout(GlobalClusterRemovalTimeout), + }, + Schema: map[string]*schema.Schema{ "arn": { Type: schema.TypeString, @@ -153,7 +163,7 @@ func resourceGlobalClusterCreate(d *schema.ResourceData, meta interface{}) error d.SetId(aws.StringValue(output.GlobalCluster.GlobalClusterIdentifier)) - if err := waitForGlobalClusterCreation(conn, d.Id()); err != nil { + if err := waitForGlobalClusterCreation(conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { return fmt.Errorf("error waiting for RDS Global Cluster (%s) availability: %s", d.Id(), err) } @@ -213,7 +223,7 @@ func resourceGlobalClusterUpdate(d *schema.ResourceData, meta interface{}) error } if d.HasChange("engine_version") { - if err := resourceGlobalClusterUpgradeEngineVersion(d, conn); err != nil { + if err := globalClusterUpgradeEngineVersion(d, conn); err != nil { return err } } @@ -229,14 +239,14 @@ func resourceGlobalClusterUpdate(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("error deleting RDS Global Cluster: %s", err) } - if err := waitForGlobalClusterUpdate(conn, d.Id()); err != nil { + if err := waitForGlobalClusterUpdate(conn, d.Id(), d.Timeout(schema.TimeoutUpdate)); err != nil { return fmt.Errorf("error waiting for RDS Global Cluster (%s) update: %s", d.Id(), err) } return resourceGlobalClusterRead(d, meta) } -func resourceGlobalClusterGetIdByARN(conn *rds.RDS, arn string) string { +func globalClusterGetIDByARN(conn *rds.RDS, arn string) string { result, err := conn.DescribeDBClusters(&rds.DescribeDBClustersInput{}) if err != nil { return "" @@ -281,7 +291,7 @@ func resourceGlobalClusterDelete(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("error removing RDS DB Cluster (%s) from Global Cluster (%s): %w", dbClusterArn, d.Id(), err) } - if err := waitForGlobalClusterRemoval(conn, dbClusterArn); err != nil { + if err := waitForGlobalClusterRemoval(conn, dbClusterArn, d.Timeout(schema.TimeoutDelete)); err != nil { return fmt.Errorf("error waiting for RDS DB Cluster (%s) removal from RDS Global Cluster (%s): %w", dbClusterArn, d.Id(), err) } } @@ -295,7 +305,7 @@ func resourceGlobalClusterDelete(d *schema.ResourceData, meta interface{}) error // Allow for eventual consistency // InvalidGlobalClusterStateFault: Global Cluster arn:aws:rds::123456789012:global-cluster:tf-acc-test-5618525093076697001-0 is not empty - err := resource.Retry(1*time.Minute, func() *resource.RetryError { + err := resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { _, err := conn.DeleteGlobalCluster(input) if tfawserr.ErrMessageContains(err, rds.ErrCodeInvalidGlobalClusterStateFault, "is not empty") { @@ -321,7 +331,7 @@ func resourceGlobalClusterDelete(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("error deleting RDS Global Cluster: %s", err) } - if err := WaitForGlobalClusterDeletion(conn, d.Id()); err != nil { + if err := WaitForGlobalClusterDeletion(conn, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil { return fmt.Errorf("error waiting for RDS Global Cluster (%s) deletion: %s", d.Id(), err) } @@ -414,7 +424,7 @@ func DescribeGlobalClusterFromClusterARN(conn *rds.RDS, dbClusterARN string) (*r return globalCluster, err } -func rdsGlobalClusterRefreshFunc(conn *rds.RDS, globalClusterID string) resource.StateRefreshFunc { +func globalClusterRefreshFunc(conn *rds.RDS, globalClusterID string) resource.StateRefreshFunc { return func() (interface{}, string, error) { globalCluster, err := DescribeGlobalCluster(conn, globalClusterID) @@ -434,12 +444,12 @@ func rdsGlobalClusterRefreshFunc(conn *rds.RDS, globalClusterID string) resource } } -func waitForGlobalClusterCreation(conn *rds.RDS, globalClusterID string) error { +func waitForGlobalClusterCreation(conn *rds.RDS, globalClusterID string, timeout time.Duration) error { stateConf := &resource.StateChangeConf{ Pending: []string{"creating"}, Target: []string{"available"}, - Refresh: rdsGlobalClusterRefreshFunc(conn, globalClusterID), - Timeout: 10 * time.Minute, + Refresh: globalClusterRefreshFunc(conn, globalClusterID), + Timeout: timeout, } log.Printf("[DEBUG] Waiting for RDS Global Cluster (%s) availability", globalClusterID) @@ -448,12 +458,12 @@ func waitForGlobalClusterCreation(conn *rds.RDS, globalClusterID string) error { return err } -func waitForGlobalClusterUpdate(conn *rds.RDS, globalClusterID string) error { +func waitForGlobalClusterUpdate(conn *rds.RDS, globalClusterID string, timeout time.Duration) error { stateConf := &resource.StateChangeConf{ Pending: []string{"modifying", "upgrading"}, Target: []string{"available"}, - Refresh: rdsGlobalClusterRefreshFunc(conn, globalClusterID), - Timeout: 10 * time.Minute, + Refresh: globalClusterRefreshFunc(conn, globalClusterID), + Timeout: timeout, Delay: 30 * time.Second, } @@ -463,15 +473,15 @@ func waitForGlobalClusterUpdate(conn *rds.RDS, globalClusterID string) error { return err } -func WaitForGlobalClusterDeletion(conn *rds.RDS, globalClusterID string) error { +func WaitForGlobalClusterDeletion(conn *rds.RDS, globalClusterID string, timeout time.Duration) error { stateConf := &resource.StateChangeConf{ Pending: []string{ "available", "deleting", }, Target: []string{"deleted"}, - Refresh: rdsGlobalClusterRefreshFunc(conn, globalClusterID), - Timeout: 10 * time.Minute, + Refresh: globalClusterRefreshFunc(conn, globalClusterID), + Timeout: timeout, NotFoundChecks: 1, } @@ -485,11 +495,11 @@ func WaitForGlobalClusterDeletion(conn *rds.RDS, globalClusterID string) error { return err } -func waitForGlobalClusterRemoval(conn *rds.RDS, dbClusterIdentifier string) error { +func waitForGlobalClusterRemoval(conn *rds.RDS, dbClusterIdentifier string, timeout time.Duration) error { var globalCluster *rds.GlobalCluster stillExistsErr := fmt.Errorf("RDS DB Cluster still exists in RDS Global Cluster") - err := resource.Retry(rdsGlobalClusterRemovalTimeout, func() *resource.RetryError { + err := resource.Retry(timeout, func() *resource.RetryError { var err error globalCluster, err = DescribeGlobalClusterFromClusterARN(conn, dbClusterIdentifier) @@ -520,13 +530,13 @@ func waitForGlobalClusterRemoval(conn *rds.RDS, dbClusterIdentifier string) erro return nil } -func resourceGlobalClusterUpgradeMajorEngineVersion(clusterId string, engineVersion string, conn *rds.RDS) error { +func globalClusterUpgradeMajorEngineVersion(clusterId string, engineVersion string, conn *rds.RDS) error { input := &rds.ModifyGlobalClusterInput{ GlobalClusterIdentifier: aws.String(clusterId), } input.AllowMajorVersionUpgrade = aws.Bool(true) input.EngineVersion = aws.String(engineVersion) - err := resource.Retry(rdsClusterInitiateUpgradeTimeout, func() *resource.RetryError { + err := resource.Retry(clusterInitiateUpgradeTimeout, func() *resource.RetryError { _, err := conn.ModifyGlobalCluster(input) if err != nil { if tfawserr.ErrCodeEquals(err, rds.ErrCodeGlobalClusterNotFoundFault) { @@ -547,26 +557,42 @@ func resourceGlobalClusterUpgradeMajorEngineVersion(clusterId string, engineVers return err } -func resourceGlobalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, engineVersion string, conn *rds.RDS) error { +func globalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, engineVersion string, conn *rds.RDS) error { for _, clusterMemberRaw := range clusterMembers.List() { clusterMember := clusterMemberRaw.(map[string]interface{}) + if clusterMemberArn, ok := clusterMember["db_cluster_arn"]; ok && clusterMemberArn.(string) != "" { + parsedARN, err := arn.Parse(clusterMemberArn.(string)) + + if err != nil { + return fmt.Errorf("could not parse ARN while upgrading RDS Global Cluster minor engine version: %w", err) + } + + dbi := "" + + if parsedARN.Resource != "" { + parts := strings.Split(parsedARN.Resource, ":") + + if len(parts) < 2 { + return fmt.Errorf("could not get DB Cluster ID from parsing ARN while upgrading RDS Global Cluster minor engine version: %w", err) + } + + dbi = parts[1] + } + modInput := &rds.ModifyDBClusterInput{ ApplyImmediately: aws.Bool(true), - DBClusterIdentifier: aws.String(clusterMemberArn.(string)), + DBClusterIdentifier: aws.String(dbi), EngineVersion: aws.String(engineVersion), } - err := resource.Retry(rdsClusterInitiateUpgradeTimeout, func() *resource.RetryError { + + err = resource.Retry(clusterInitiateUpgradeTimeout, func() *resource.RetryError { _, err := conn.ModifyDBCluster(modInput) if err != nil { if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "IAM role ARN value is invalid or does not include the required permissions") { return resource.RetryableError(err) } - if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "Invalid database cluster identifier") { - return resource.RetryableError(err) - } - if tfawserr.ErrMessageContains(err, rds.ErrCodeInvalidDBClusterStateFault, "Cannot modify engine version without a primary instance in DB cluster") { return resource.NonRetryableError(err) } @@ -592,11 +618,11 @@ func resourceGlobalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, return nil } -func resourceGlobalClusterUpgradeEngineVersion(d *schema.ResourceData, conn *rds.RDS) error { +func globalClusterUpgradeEngineVersion(d *schema.ResourceData, conn *rds.RDS) error { log.Printf("[DEBUG] Upgrading RDS Global Cluster (%s) engine version: %s", d.Id(), d.Get("engine_version")) - err := resourceGlobalClusterUpgradeMajorEngineVersion(d.Id(), d.Get("engine_version").(string), conn) + err := globalClusterUpgradeMajorEngineVersion(d.Id(), d.Get("engine_version").(string), conn) if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "ModifyGlobalCluster only supports Major Version Upgrades. To patch the members of your global cluster to a newer minor version you need to call ModifyDbCluster in each one of them.") { - err = resourceGlobalClusterUpgradeMinorEngineVersion(d.Get("global_cluster_members").(*schema.Set), d.Get("engine_version").(string), conn) + err = globalClusterUpgradeMinorEngineVersion(d.Get("global_cluster_members").(*schema.Set), d.Get("engine_version").(string), conn) if err != nil { return err } @@ -608,7 +634,7 @@ func resourceGlobalClusterUpgradeEngineVersion(d *schema.ResourceData, conn *rds return err } for _, clusterMember := range globalCluster.GlobalClusterMembers { - err := waitForRDSClusterUpdate(conn, resourceGlobalClusterGetIdByARN(conn, aws.StringValue(clusterMember.DBClusterArn)), d.Timeout(schema.TimeoutUpdate)) + err := waitForClusterUpdate(conn, globalClusterGetIDByARN(conn, aws.StringValue(clusterMember.DBClusterArn)), d.Timeout(schema.TimeoutUpdate)) if err != nil { return err } diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index db9c725e3f0..638ada23f4c 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -210,12 +210,14 @@ func TestAccRDSGlobalCluster_engineVersionUpdateMinor(t *testing.T) { CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { + //Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.6.mysql_aurora.1.22.2"), Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-postgresql", "13.4"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), ), }, { + //Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.6.mysql_aurora.1.23.2"), Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-postgresql", "13.5"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster2), @@ -488,7 +490,7 @@ func testAccCheckGlobalClusterDisappears(globalCluster *rds.GlobalCluster) resou return err } - return tfrds.WaitForGlobalClusterDeletion(conn, aws.StringValue(globalCluster.GlobalClusterIdentifier)) + return tfrds.WaitForGlobalClusterDeletion(conn, aws.StringValue(globalCluster.GlobalClusterIdentifier), tfrds.GlobalClusterRemovalTimeout) } } diff --git a/internal/service/rds/wait.go b/internal/service/rds/wait.go index c55a9ac8399..096fe77f506 100644 --- a/internal/service/rds/wait.go +++ b/internal/service/rds/wait.go @@ -8,7 +8,7 @@ import ( ) const ( - rdsClusterInitiateUpgradeTimeout = 5 * time.Minute + clusterInitiateUpgradeTimeout = 5 * time.Minute dbClusterRoleAssociationCreatedTimeout = 5 * time.Minute dbClusterRoleAssociationDeletedTimeout = 5 * time.Minute diff --git a/website/docs/r/rds_global_cluster.html.markdown b/website/docs/r/rds_global_cluster.html.markdown index 48aa664fd2e..ad39c887419 100644 --- a/website/docs/r/rds_global_cluster.html.markdown +++ b/website/docs/r/rds_global_cluster.html.markdown @@ -187,6 +187,15 @@ In addition to all arguments above, the following attributes are exported: * `global_cluster_resource_id` - AWS Region-unique, immutable identifier for the global database cluster. This identifier is found in AWS CloudTrail log entries whenever the AWS KMS key for the DB cluster is accessed * `id` - RDS Global Cluster identifier +## Timeouts + +`aws_rds_global_cluster` provides the following +[Timeouts](https://www.terraform.io/docs/configuration/blocks/resources/syntax.html#operation-timeouts) configuration options: + +- `create` - (Default `30 minutes`) +- `update` - (Default `30 minutes`) +- `delete` - (Default `30 minutes`) + ## Import `aws_rds_global_cluster` can be imported by using the RDS Global Cluster identifier, e.g., From a585794526634e66bceb9345a1da72134ffce3b8 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Thu, 10 Mar 2022 20:56:31 -0500 Subject: [PATCH 126/229] Update changelog --- .changelog/23560.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.changelog/23560.txt b/.changelog/23560.txt index ad9eaf3f32f..681fa41670f 100644 --- a/.changelog/23560.txt +++ b/.changelog/23560.txt @@ -8,4 +8,8 @@ resource/aws_db_instance: Fix issues where configured update timeout was not res ```release-note:bug resource/aws_rds_global_cluster: Fix in-place DB Cluster minor version upgrade error: "Invalid database cluster identifier" -``` \ No newline at end of file +``` + +```release-note:enhancement +resource/aws_rds_global_cluster: Add configurable timeouts +``` From f158a604d6097385e57df2735930853351f517d0 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Thu, 10 Mar 2022 21:18:12 -0500 Subject: [PATCH 127/229] Add session to client --- internal/conns/conns.go | 2 + internal/service/rds/global_cluster_test.go | 103 +++++++++++++++++++- internal/service/rds/sweep.go | 2 +- 3 files changed, 103 insertions(+), 4 deletions(-) diff --git a/internal/conns/conns.go b/internal/conns/conns.go index e0658523a0b..db3f008434a 100644 --- a/internal/conns/conns.go +++ b/internal/conns/conns.go @@ -1141,6 +1141,7 @@ type AWSClient struct { ServiceDiscoveryConn *servicediscovery.ServiceDiscovery ServiceQuotasConn *servicequotas.ServiceQuotas SESConn *ses.SES + Session *session.Session SESV2Conn *sesv2.SESV2 SFNConn *sfn.SFN ShieldConn *shield.Shield @@ -1540,6 +1541,7 @@ func (c *Config) Client(ctx context.Context) (interface{}, diag.Diagnostics) { ServiceQuotasConn: servicequotas.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[ServiceQuotas])})), SESConn: ses.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[SES])})), SESV2Conn: sesv2.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[SESV2])})), + Session: sess, SFNConn: sfn.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[SFN])})), SignerConn: signer.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[Signer])})), SimpleDBConn: simpledb.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[SimpleDB])})), diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index 638ada23f4c..4ab1dd98861 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" 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/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" @@ -198,7 +199,7 @@ func TestAccRDSGlobalCluster_EngineVersion_aurora(t *testing.T) { }) } -func TestAccRDSGlobalCluster_engineVersionUpdateMinor(t *testing.T) { +func TestAccRDSGlobalCluster_EngineVersion_updateMinor(t *testing.T) { var globalCluster1, globalCluster2 rds.GlobalCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_global_cluster.test" @@ -234,7 +235,7 @@ func TestAccRDSGlobalCluster_engineVersionUpdateMinor(t *testing.T) { }) } -func TestAccRDSGlobalCluster_engineVersionUpdateMajor(t *testing.T) { +func TestAccRDSGlobalCluster_EngineVersion_updateMajor(t *testing.T) { var globalCluster1, globalCluster2 rds.GlobalCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_global_cluster.test" @@ -268,6 +269,36 @@ func TestAccRDSGlobalCluster_engineVersionUpdateMajor(t *testing.T) { }) } +func TestAccRDSGlobalCluster_EngineVersion_updateMinorMultiRegion(t *testing.T) { + var providers []*schema.Provider + var globalCluster1, globalCluster2 rds.GlobalCluster + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_rds_global_cluster.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckGlobalCluster(t) }, + ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), + ProviderFactories: acctest.FactoriesAlternate(&providers), + CheckDestroy: testAccCheckGlobalClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGlobalClusterEngineVersionUpgradeMultiRegionConfig(rName, "aurora", "5.6.mysql_aurora.1.22.2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGlobalClusterExists(resourceName, &globalCluster1), + ), + }, + { + Config: testAccGlobalClusterEngineVersionUpgradeMultiRegionConfig(rName, "aurora", "5.6.mysql_aurora.1.23.2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGlobalClusterExists(resourceName, &globalCluster2), + testAccCheckGlobalClusterNotRecreated(&globalCluster1, &globalCluster2), + resource.TestCheckResourceAttr(resourceName, "engine_version", "5.6.mysql_aurora.1.23.2"), + ), + }, + }, + }) +} + func TestAccRDSGlobalCluster_EngineVersion_auroraMySQL(t *testing.T) { var globalCluster1 rds.GlobalCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -295,7 +326,7 @@ func TestAccRDSGlobalCluster_EngineVersion_auroraMySQL(t *testing.T) { }) } -func TestAccRDSGlobalCluster_EngineVersion_auroraPostgresql(t *testing.T) { +func TestAccRDSGlobalCluster_EngineVersion_auroraPostgreSQL(t *testing.T) { var globalCluster1 rds.GlobalCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_global_cluster.test" @@ -627,6 +658,72 @@ resource "aws_rds_cluster_instance" "test" { `, engine, engineVersion, rName) } +func testAccGlobalClusterEngineVersionUpgradeMultiRegionConfig(rName, engine, engineVersion string) string { + return acctest.ConfigCompose( + acctest.ConfigAlternateRegionProvider(), + fmt.Sprintf(` +resource "aws_rds_global_cluster" "test" { + engine = %[1]q + engine_version = %[2]q + global_cluster_identifier = %[3]q +} + +resource "aws_rds_cluster" "test" { + allow_major_version_upgrade = true + apply_immediately = true + cluster_identifier = %[3]q + database_name = "totoro" + engine = aws_rds_global_cluster.test.engine + engine_version = aws_rds_global_cluster.test.engine_version + global_cluster_identifier = aws_rds_global_cluster.test.global_cluster_identifier + master_password = "mustbeeightcharacters" + master_username = "test" + skip_final_snapshot = true + + lifecycle { + ignore_changes = [global_cluster_identifier] + } +} + +resource "aws_rds_cluster_instance" "test" { + apply_immediately = true + cluster_identifier = aws_rds_cluster.test.id + engine = aws_rds_global_cluster.test.engine + engine_version = aws_rds_global_cluster.test.engine_version + identifier = %[3]q + instance_class = "db.r3.large" +} + +resource "aws_rds_cluster" "test2" { + provider = "awsalternate" + + allow_major_version_upgrade = true + apply_immediately = true + cluster_identifier = "%[3]s-2" + engine = %[1]q + engine_version = %[2]q + global_cluster_identifier = aws_rds_global_cluster.test.global_cluster_identifier + replication_source_identifier = aws_rds_cluster.test.arn + skip_final_snapshot = true + + lifecycle { + ignore_changes = [global_cluster_identifier] + } +} + +resource "aws_rds_cluster_instance" "test2" { + provider = "awsalternate" + + apply_immediately = true + cluster_identifier = aws_rds_cluster.test2.id + engine = %[1]q + engine_version = %[2]q + identifier = "%[3]s-2" + instance_class = "db.r3.large" +} +`, engine, engineVersion, rName)) +} + func testAccGlobalClusterSourceClusterIdentifierConfig(rName string) string { return fmt.Sprintf(` data "aws_rds_engine_version" "default" { diff --git a/internal/service/rds/sweep.go b/internal/service/rds/sweep.go index 8997ecea70e..7af82b991bf 100644 --- a/internal/service/rds/sweep.go +++ b/internal/service/rds/sweep.go @@ -346,7 +346,7 @@ func sweepGlobalClusters(region string) error { continue } - if err := WaitForGlobalClusterDeletion(conn, id); err != nil { + if err := WaitForGlobalClusterDeletion(conn, id, 30*time.Minute); err != nil { log.Printf("[ERROR] Failure while waiting for RDS Global Cluster (%s) to be deleted: %s", id, err) } } From c7f22d7f97606d9fcbaea4238b894755e04dd336 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Thu, 10 Mar 2022 21:46:28 -0500 Subject: [PATCH 128/229] Glint in your eye --- internal/service/rds/global_cluster.go | 30 +++++++++++++++------ internal/service/rds/global_cluster_test.go | 2 +- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index 994b8f2c46b..2d2b4165bb6 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -223,7 +223,7 @@ func resourceGlobalClusterUpdate(d *schema.ResourceData, meta interface{}) error } if d.HasChange("engine_version") { - if err := globalClusterUpgradeEngineVersion(d, conn); err != nil { + if err := globalClusterUpgradeEngineVersion(d, meta); err != nil { return err } } @@ -530,7 +530,7 @@ func waitForGlobalClusterRemoval(conn *rds.RDS, dbClusterIdentifier string, time return nil } -func globalClusterUpgradeMajorEngineVersion(clusterId string, engineVersion string, conn *rds.RDS) error { +func globalClusterUpgradeMajorEngineVersion(conn *rds.RDS, clusterId string, engineVersion string) error { input := &rds.ModifyGlobalClusterInput{ GlobalClusterIdentifier: aws.String(clusterId), } @@ -557,7 +557,9 @@ func globalClusterUpgradeMajorEngineVersion(clusterId string, engineVersion stri return err } -func globalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, engineVersion string, conn *rds.RDS) error { +func globalClusterUpgradeMinorEngineVersion(meta interface{}, clusterMembers *schema.Set, engineVersion string) error { + conn := meta.(*conns.AWSClient).RDSConn + for _, clusterMemberRaw := range clusterMembers.List() { clusterMember := clusterMemberRaw.(map[string]interface{}) @@ -569,6 +571,10 @@ func globalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, engineVe } dbi := "" + useConn := conn + + // DBClusterIdentifier supposedly can be either ARN or ID, and both used to work, + // but as of now, only ID works if parsedARN.Resource != "" { parts := strings.Split(parsedARN.Resource, ":") @@ -580,6 +586,10 @@ func globalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, engineVe dbi = parts[1] } + if parsedARN.Region != meta.(*conns.AWSClient).Region { + useConn = rds.New(meta.(*conns.AWSClient).Session, aws.NewConfig().WithRegion(parsedARN.Region)) + } + modInput := &rds.ModifyDBClusterInput{ ApplyImmediately: aws.Bool(true), DBClusterIdentifier: aws.String(dbi), @@ -587,7 +597,7 @@ func globalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, engineVe } err = resource.Retry(clusterInitiateUpgradeTimeout, func() *resource.RetryError { - _, err := conn.ModifyDBCluster(modInput) + _, err := useConn.ModifyDBCluster(modInput) if err != nil { if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "IAM role ARN value is invalid or does not include the required permissions") { return resource.RetryableError(err) @@ -604,12 +614,14 @@ func globalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, engineVe } return nil }) + if tfresource.TimedOut(err) { - _, err := conn.ModifyDBCluster(modInput) + _, err := useConn.ModifyDBCluster(modInput) if err != nil { return err } } + if err != nil { return fmt.Errorf("failed to update engine_version on RDS Global Cluster member (%s): %s", clusterMemberArn, err) } @@ -618,11 +630,13 @@ func globalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, engineVe return nil } -func globalClusterUpgradeEngineVersion(d *schema.ResourceData, conn *rds.RDS) error { +func globalClusterUpgradeEngineVersion(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).RDSConn + log.Printf("[DEBUG] Upgrading RDS Global Cluster (%s) engine version: %s", d.Id(), d.Get("engine_version")) - err := globalClusterUpgradeMajorEngineVersion(d.Id(), d.Get("engine_version").(string), conn) + err := globalClusterUpgradeMajorEngineVersion(conn, d.Id(), d.Get("engine_version").(string)) if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "ModifyGlobalCluster only supports Major Version Upgrades. To patch the members of your global cluster to a newer minor version you need to call ModifyDbCluster in each one of them.") { - err = globalClusterUpgradeMinorEngineVersion(d.Get("global_cluster_members").(*schema.Set), d.Get("engine_version").(string), conn) + err = globalClusterUpgradeMinorEngineVersion(meta, d.Get("global_cluster_members").(*schema.Set), d.Get("engine_version").(string)) if err != nil { return err } diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index 4ab1dd98861..2da19aa07e9 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -708,7 +708,7 @@ resource "aws_rds_cluster" "test2" { lifecycle { ignore_changes = [global_cluster_identifier] - } + } } resource "aws_rds_cluster_instance" "test2" { From b0a79151caa5c731358a116baf3939b784e30d5b Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Fri, 11 Mar 2022 08:59:39 -0500 Subject: [PATCH 129/229] Remove bad comment --- internal/service/rds/global_cluster_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index 2da19aa07e9..d73d82f8883 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -624,8 +624,6 @@ resource "aws_rds_global_cluster" "test" { global_cluster_identifier = %[3]q } -// checkout the newly working global cluster stuff in cluster - resource "aws_rds_cluster" "test" { apply_immediately = true allow_major_version_upgrade = true From fb6db6f1c116e42e67a99ab5832efbee4d176d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Prieto=20Ballester?= Date: Fri, 11 Mar 2022 16:40:29 +0100 Subject: [PATCH 130/229] Add Pre Login Banners and Post Login Banners to AWS Transfer Family --- internal/service/transfer/server.go | 34 ++++++++++++++++++++ internal/service/transfer/server_test.go | 3 ++ website/docs/r/transfer_server.html.markdown | 2 ++ 3 files changed, 39 insertions(+) diff --git a/internal/service/transfer/server.go b/internal/service/transfer/server.go index f21a650fa2e..36a6fcf5687 100644 --- a/internal/service/transfer/server.go +++ b/internal/service/transfer/server.go @@ -142,6 +142,20 @@ func ResourceServer() *schema.Resource { ValidateFunc: validation.StringLenBetween(0, 4096), }, + "pre_display_banner": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ValidateFunc: validation.StringLenBetween(0, 512), + }, + + "post_display_banner": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ValidateFunc: validation.StringLenBetween(0, 512), + }, + "host_key_fingerprint": { Type: schema.TypeString, Computed: true, @@ -243,6 +257,16 @@ func resourceServerCreate(d *schema.ResourceData, meta interface{}) error { input.IdentityProviderDetails.Function = aws.String(v.(string)) } + if v, ok := d.GetOk("pre_display_banner"); ok { + input.PreAuthenticationLoginBanner = aws.String(v.(string)) + + } + + if v, ok := d.GetOk("post_display_banner"); ok { + input.PostAuthenticationLoginBanner = aws.String(v.(string)) + + } + if v, ok := d.GetOk("host_key"); ok { input.HostKey = aws.String(v.(string)) } @@ -378,6 +402,8 @@ func resourceServerRead(d *schema.ResourceData, meta interface{}) error { } else { d.Set("function", "") } + d.Set("pre_display_banner", output.PreAuthenticationLoginBanner) + d.Set("post_display_banner", output.PostAuthenticationLoginBanner) d.Set("host_key_fingerprint", output.HostKeyFingerprint) d.Set("identity_provider_type", output.IdentityProviderType) if output.IdentityProviderDetails != nil { @@ -521,6 +547,14 @@ func resourceServerUpdate(d *schema.ResourceData, meta interface{}) error { offlineUpdate = true } + if d.HasChange("pre_display_banner") { + input.PreAuthenticationLoginBanner = aws.String(d.Get("pre_display_banner").(string)) + } + + if d.HasChange("post_display_banner") { + input.PostAuthenticationLoginBanner = aws.String(d.Get("post_display_banner").(string)) + } + if d.HasChange("host_key") { if attr, ok := d.GetOk("host_key"); ok { input.HostKey = aws.String(attr.(string)) diff --git a/internal/service/transfer/server_test.go b/internal/service/transfer/server_test.go index 8cdae5c377a..37d2d0236a1 100644 --- a/internal/service/transfer/server_test.go +++ b/internal/service/transfer/server_test.go @@ -51,6 +51,8 @@ func testAccServer_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "endpoint_type", "PUBLIC"), resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"), resource.TestCheckResourceAttr(resourceName, "function", ""), + resource.TestCheckResourceAttr(resourceName, "pre_display_banner", "Pre DisplayBanner"), + resource.TestCheckResourceAttr(resourceName, "post_display_banner", "Post Display Banner"), resource.TestCheckNoResourceAttr(resourceName, "host_key"), resource.TestCheckResourceAttrSet(resourceName, "host_key_fingerprint"), resource.TestCheckResourceAttr(resourceName, "identity_provider_type", "SERVICE_MANAGED"), @@ -81,6 +83,7 @@ func testAccServer_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "endpoint_type", "PUBLIC"), resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"), resource.TestCheckResourceAttr(resourceName, "function", ""), + resource.TestCheckResourceAttr(resourceName, "display_banners"), resource.TestCheckNoResourceAttr(resourceName, "host_key"), resource.TestCheckResourceAttrSet(resourceName, "host_key_fingerprint"), resource.TestCheckResourceAttr(resourceName, "identity_provider_type", "SERVICE_MANAGED"), diff --git a/website/docs/r/transfer_server.html.markdown b/website/docs/r/transfer_server.html.markdown index 004b76a4890..435247cfc3c 100644 --- a/website/docs/r/transfer_server.html.markdown +++ b/website/docs/r/transfer_server.html.markdown @@ -103,6 +103,8 @@ The following arguments are supported: * `function` - (Optional) The ARN for a lambda function to use for the Identity provider. * `logging_role` - (Optional) Amazon Resource Name (ARN) of an IAM role that allows the service to write your SFTP users’ activity to your Amazon CloudWatch logs for monitoring and auditing purposes. * `force_destroy` - (Optional) A boolean that indicates all users associated with the server should be deleted so that the Server can be destroyed without error. The default value is `false`. This option only applies to servers configured with a `SERVICE_MANAGED` `identity_provider_type`. +* `pre_display_banner`- (Optional) Specify a string to display when users connect to a server. This string is displayed before the user authenticates. +* `post_display_banner`- (Optional) Specify a string to display when users connect to a server. This string is displayed after the user authenticates. The SFTP protocol does not support post-authentication display banners. * `security_policy_name` - (Optional) Specifies the name of the security policy that is attached to the server. Possible values are `TransferSecurityPolicy-2018-11`, `TransferSecurityPolicy-2020-06`, and `TransferSecurityPolicy-FIPS-2020-06`. Default value is: `TransferSecurityPolicy-2018-11`. * `tags` - (Optional) A map of tags to assign to the resource. If configured with a provider [`default_tags` configuration block](https://www.terraform.io/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. From a25db2bc1f5d583fc534a5e571772d54d9b750b9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 11 Mar 2022 12:05:16 -0500 Subject: [PATCH 131/229] r/aws_networkmanager_customer_gateway_association: New resource. Acceptance test output: % make testacc TESTARGS='-run=TestAccNetworkManageCustomerGatewayAssociation_serial' PKG=networkmanager ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/networkmanager/... -v -count 1 -parallel 20 -run=TestAccNetworkManageCustomerGatewayAssociation_serial -timeout 180m === RUN TestAccNetworkManageCustomerGatewayAssociation_serial === RUN TestAccNetworkManageCustomerGatewayAssociation_serial/basic === RUN TestAccNetworkManageCustomerGatewayAssociation_serial/disappears === RUN TestAccNetworkManageCustomerGatewayAssociation_serial/disappears_CustomerGateway --- PASS: TestAccNetworkManageCustomerGatewayAssociation_serial (2310.51s) --- PASS: TestAccNetworkManageCustomerGatewayAssociation_serial/basic (857.13s) --- PASS: TestAccNetworkManageCustomerGatewayAssociation_serial/disappears (738.83s) --- PASS: TestAccNetworkManageCustomerGatewayAssociation_serial/disappears_CustomerGateway (714.55s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 2314.041s --- .changelog/13251.txt | 4 + internal/provider/provider.go | 1 + .../customer_gateway_association.go | 337 ++++++++++++++++++ .../customer_gateway_association_test.go | 232 ++++++++++++ internal/service/networkmanager/errors.go | 13 + .../service/networkmanager/global_network.go | 28 +- ...customer_gateway_association.html.markdown | 80 +++++ 7 files changed, 693 insertions(+), 2 deletions(-) create mode 100644 internal/service/networkmanager/customer_gateway_association.go create mode 100644 internal/service/networkmanager/customer_gateway_association_test.go create mode 100644 website/docs/r/networkmanager_customer_gateway_association.html.markdown diff --git a/.changelog/13251.txt b/.changelog/13251.txt index 7098f9f1fae..25718c95924 100644 --- a/.changelog/13251.txt +++ b/.changelog/13251.txt @@ -22,6 +22,10 @@ aws_networkmanager_link aws_networkmanager_link_association ``` +```release-note:new-resource +aws_networkmanager_customer_gateway_association +``` + ```release-note:new-data-source aws_networkmanager_global_network ``` diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 88e0b35bf20..dea1046204f 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1586,6 +1586,7 @@ func Provider() *schema.Provider { "aws_networkfirewall_resource_policy": networkfirewall.ResourceResourcePolicy(), "aws_networkfirewall_rule_group": networkfirewall.ResourceRuleGroup(), + "aws_networkmanager_customer_gateway_association": networkmanager.ResourceCustomerGatewayAssociation(), "aws_networkmanager_device": networkmanager.ResourceDevice(), "aws_networkmanager_global_network": networkmanager.ResourceGlobalNetwork(), "aws_networkmanager_link": networkmanager.ResourceLink(), diff --git a/internal/service/networkmanager/customer_gateway_association.go b/internal/service/networkmanager/customer_gateway_association.go new file mode 100644 index 00000000000..dbbc4db3d92 --- /dev/null +++ b/internal/service/networkmanager/customer_gateway_association.go @@ -0,0 +1,337 @@ +package networkmanager + +import ( + "context" + "fmt" + "log" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" +) + +func ResourceCustomerGatewayAssociation() *schema.Resource { + return &schema.Resource{ + CreateWithoutTimeout: resourceCustomerGatewayAssociationCreate, + ReadWithoutTimeout: resourceCustomerGatewayAssociationRead, + DeleteWithoutTimeout: resourceCustomerGatewayAssociationDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "customer_gateway_arn": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "device_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "global_network_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "link_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + }, + } +} + +func resourceCustomerGatewayAssociationCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + globalNetworkID := d.Get("global_network_id").(string) + customerGatewayARN := d.Get("customer_gateway_arn").(string) + id := CustomerGatewayAssociationCreateResourceID(globalNetworkID, customerGatewayARN) + input := &networkmanager.AssociateCustomerGatewayInput{ + CustomerGatewayArn: aws.String(customerGatewayARN), + DeviceId: aws.String(d.Get("device_id").(string)), + GlobalNetworkId: aws.String(globalNetworkID), + } + + if v, ok := d.GetOk("link_id"); ok { + input.LinkId = aws.String(v.(string)) + } + + log.Printf("[DEBUG] Creating Network Manager Customer Gateway Association: %s", input) + _, err := tfresource.RetryWhenContext(ctx, customerGatewayAssociationResourceNotFoundExceptionTimeout, + func() (interface{}, error) { + return conn.AssociateCustomerGatewayWithContext(ctx, input) + }, + func(err error) (bool, error) { + // Wait out eventual consistency errors like: + // + // ResourceNotFoundException: Resource not found. + // { + // RespMetadata: { + // StatusCode: 404, + // RequestID: "530d124c-2af8-4adf-be73-cee3793042f3" + // }, + // Message_: "Resource not found.", + // ResourceId: "arn:aws:ec2:us-west-2:123456789012:customer-gateway/cgw-07c83f17516ae28fd", + // ResourceType: "customer-gateway" + // } + if resourceNotFoundExceptionResourceIDEquals(err, customerGatewayARN) { + return true, err + } + + return false, err + }, + ) + + if err != nil { + return diag.Errorf("error creating Network Manager Customer Gateway Association (%s): %s", id, err) + } + + d.SetId(id) + + if _, err := waitCustomerGatewayAssociationCreated(ctx, conn, globalNetworkID, customerGatewayARN, d.Timeout(schema.TimeoutCreate)); err != nil { + return diag.Errorf("error waiting for Network Manager Customer Gateway Association (%s) create: %s", d.Id(), err) + } + + return resourceCustomerGatewayAssociationRead(ctx, d, meta) +} + +func resourceCustomerGatewayAssociationRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + globalNetworkID, customerGatewayARN, err := CustomerGatewayAssociationParseResourceID(d.Id()) + + if err != nil { + return diag.FromErr(err) + } + + output, err := FindCustomerGatewayAssociationByTwoPartKey(ctx, conn, globalNetworkID, customerGatewayARN) + + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Network Manager Customer Gateway Association %s not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return diag.Errorf("error reading Network Manager Customer Gateway Association (%s): %s", d.Id(), err) + } + + d.Set("customer_gateway_arn", output.CustomerGatewayArn) + d.Set("device_id", output.DeviceId) + d.Set("global_network_id", output.GlobalNetworkId) + d.Set("link_id", output.LinkId) + + return nil +} + +func resourceCustomerGatewayAssociationDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + globalNetworkID, customerGatewayARN, err := CustomerGatewayAssociationParseResourceID(d.Id()) + + if err != nil { + return diag.FromErr(err) + } + + err = disassociateCustomerGateway(ctx, conn, globalNetworkID, customerGatewayARN, d.Timeout(schema.TimeoutDelete)) + + if err != nil { + return diag.FromErr(err) + } + + return nil +} + +func disassociateCustomerGateway(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, customerGatewayARN string, timeout time.Duration) error { + id := CustomerGatewayAssociationCreateResourceID(globalNetworkID, customerGatewayARN) + + log.Printf("[DEBUG] Deleting Network Manager Customer Gateway Association: %s", id) + _, err := conn.DisassociateCustomerGatewayWithContext(ctx, &networkmanager.DisassociateCustomerGatewayInput{ + CustomerGatewayArn: aws.String(customerGatewayARN), + GlobalNetworkId: aws.String(globalNetworkID), + }) + + if globalNetworkIDNotFoundError(err) || tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeResourceNotFoundException) { + return nil + } + + if err != nil { + return fmt.Errorf("error deleting Network Manager Customer Gateway Association (%s): %w", id, err) + } + + if _, err := waitCustomerGatewayAssociationDeleted(ctx, conn, globalNetworkID, customerGatewayARN, timeout); err != nil { + return fmt.Errorf("error waiting for Network Manager Customer Gateway Association (%s) delete: %w", id, err) + } + + return nil +} + +func FindCustomerGatewayAssociation(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.GetCustomerGatewayAssociationsInput) (*networkmanager.CustomerGatewayAssociation, error) { + output, err := FindCustomerGatewayAssociations(ctx, conn, input) + + if err != nil { + return nil, err + } + + if len(output) == 0 || output[0] == nil || output[0].State == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } + + return output[0], nil +} + +func FindCustomerGatewayAssociations(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.GetCustomerGatewayAssociationsInput) ([]*networkmanager.CustomerGatewayAssociation, error) { + var output []*networkmanager.CustomerGatewayAssociation + + err := conn.GetCustomerGatewayAssociationsPagesWithContext(ctx, input, func(page *networkmanager.GetCustomerGatewayAssociationsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.CustomerGatewayAssociations { + if v == nil { + continue + } + + output = append(output, v) + } + + return !lastPage + }) + + if globalNetworkIDNotFoundError(err) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + return output, nil +} + +func FindCustomerGatewayAssociationByTwoPartKey(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, customerGatewayARN string) (*networkmanager.CustomerGatewayAssociation, error) { + input := &networkmanager.GetCustomerGatewayAssociationsInput{ + CustomerGatewayArns: aws.StringSlice([]string{customerGatewayARN}), + GlobalNetworkId: aws.String(globalNetworkID), + } + + output, err := FindCustomerGatewayAssociation(ctx, conn, input) + + if err != nil { + return nil, err + } + + if state := aws.StringValue(output.State); state == networkmanager.CustomerGatewayAssociationStateDeleted { + return nil, &resource.NotFoundError{ + Message: state, + LastRequest: input, + } + } + + // Eventual consistency check. + if aws.StringValue(output.GlobalNetworkId) != globalNetworkID || aws.StringValue(output.CustomerGatewayArn) != customerGatewayARN { + return nil, &resource.NotFoundError{ + LastRequest: input, + } + } + + return output, nil +} + +func statusCustomerGatewayAssociationState(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, customerGatewayARN string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + output, err := FindCustomerGatewayAssociationByTwoPartKey(ctx, conn, globalNetworkID, customerGatewayARN) + + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return output, aws.StringValue(output.State), nil + } +} + +func waitCustomerGatewayAssociationCreated(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, customerGatewayARN string, timeout time.Duration) (*networkmanager.CustomerGatewayAssociation, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.CustomerGatewayAssociationStatePending}, + Target: []string{networkmanager.CustomerGatewayAssociationStateAvailable}, + Timeout: timeout, + Refresh: statusCustomerGatewayAssociationState(ctx, conn, globalNetworkID, customerGatewayARN), + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*networkmanager.CustomerGatewayAssociation); ok { + return output, err + } + + return nil, err +} + +func waitCustomerGatewayAssociationDeleted(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, customerGatewayARN string, timeout time.Duration) (*networkmanager.CustomerGatewayAssociation, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.CustomerGatewayAssociationStateAvailable, networkmanager.CustomerGatewayAssociationStateDeleting}, + Target: []string{}, + Timeout: timeout, + Refresh: statusCustomerGatewayAssociationState(ctx, conn, globalNetworkID, customerGatewayARN), + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*networkmanager.CustomerGatewayAssociation); ok { + return output, err + } + + return nil, err +} + +const customerGatewayAssociationIDSeparator = "," + +func CustomerGatewayAssociationCreateResourceID(globalNetworkID, customerGatewayARN string) string { + parts := []string{globalNetworkID, customerGatewayARN} + id := strings.Join(parts, customerGatewayAssociationIDSeparator) + + return id +} + +func CustomerGatewayAssociationParseResourceID(id string) (string, string, error) { + parts := strings.Split(id, customerGatewayAssociationIDSeparator) + + if len(parts) == 2 && parts[0] != "" && parts[1] != "" { + return parts[0], parts[1], nil + } + + return "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected GLOBAL-NETWORK-ID%[2]sCUSTOMER-GATEWAY-ARN", id, customerGatewayAssociationIDSeparator) +} + +const ( + customerGatewayAssociationResourceNotFoundExceptionTimeout = 1 * time.Minute +) diff --git a/internal/service/networkmanager/customer_gateway_association_test.go b/internal/service/networkmanager/customer_gateway_association_test.go new file mode 100644 index 00000000000..15188a544cb --- /dev/null +++ b/internal/service/networkmanager/customer_gateway_association_test.go @@ -0,0 +1,232 @@ +package networkmanager_test + +import ( + "context" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/networkmanager" + 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" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tfec2 "github.com/hashicorp/terraform-provider-aws/internal/service/ec2" + tfnetworkmanager "github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" +) + +func TestAccNetworkManageCustomerGatewayAssociation_serial(t *testing.T) { + testCases := map[string]func(t *testing.T){ + "basic": testAccNetworkManageCustomerGatewayAssociation_basic, + "disappears": testAccNetworkManageCustomerGatewayAssociation_disappears, + "disappears_CustomerGateway": testAccNetworkManageCustomerGatewayAssociation_disappears_CustomerGateway, + } + + for name, tc := range testCases { + tc := tc + t.Run(name, func(t *testing.T) { + tc(t) + }) + } +} + +func testAccNetworkManageCustomerGatewayAssociation_basic(t *testing.T) { + resourceName := "aws_networkmanager_customer_gateway_association.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckCustomerGatewayAssociationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCustomerGatewayAssociationConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckCustomerGatewayAssociationExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccNetworkManageCustomerGatewayAssociation_disappears(t *testing.T) { + resourceName := "aws_networkmanager_customer_gateway_association.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckCustomerGatewayAssociationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCustomerGatewayAssociationConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckCustomerGatewayAssociationExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfnetworkmanager.ResourceCustomerGatewayAssociation(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccNetworkManageCustomerGatewayAssociation_disappears_CustomerGateway(t *testing.T) { + resourceName := "aws_networkmanager_customer_gateway_association.test" + vpnConnectionResourceName := "aws_vpn_connection.test" + customerGatewayResourceName := "aws_customer_gateway.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckCustomerGatewayAssociationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCustomerGatewayAssociationConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckCustomerGatewayAssociationExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfec2.ResourceVPNConnection(), vpnConnectionResourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfec2.ResourceCustomerGateway(), customerGatewayResourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccCheckCustomerGatewayAssociationDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_networkmanager_customer_gateway_association" { + continue + } + + globalNetworkID, customerGatewayARN, err := tfnetworkmanager.CustomerGatewayAssociationParseResourceID(rs.Primary.ID) + + if err != nil { + return err + } + + _, err = tfnetworkmanager.FindCustomerGatewayAssociationByTwoPartKey(context.TODO(), conn, globalNetworkID, customerGatewayARN) + + if tfresource.NotFound(err) { + continue + } + + if err != nil { + return err + } + + return fmt.Errorf("Network Manager Customer Gateway Association %s still exists", rs.Primary.ID) + } + + return nil +} + +func testAccCheckCustomerGatewayAssociationExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No Network Manager Customer Gateway Association ID is set") + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn + + globalNetworkID, customerGatewayARN, err := tfnetworkmanager.CustomerGatewayAssociationParseResourceID(rs.Primary.ID) + + if err != nil { + return err + } + + _, err = tfnetworkmanager.FindCustomerGatewayAssociationByTwoPartKey(context.TODO(), conn, globalNetworkID, customerGatewayARN) + + if err != nil { + return err + } + + return nil + } +} + +func testAccCustomerGatewayAssociationConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_device" "test" { + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_customer_gateway" "test" { + bgp_asn = 65534 + ip_address = "12.1.2.3" + type = "ipsec.1" + + tags = { + Name = %[1]q + } +} + +resource "aws_ec2_transit_gateway" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_vpn_connection" "test" { + customer_gateway_id = aws_customer_gateway.test.id + transit_gateway_id = aws_ec2_transit_gateway.test.id + type = aws_customer_gateway.test.type + static_routes_only = true + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_transit_gateway_registration" "test" { + global_network_id = aws_networkmanager_global_network.test.id + transit_gateway_arn = aws_ec2_transit_gateway.test.arn + + depends_on = [aws_vpn_connection.test] +} + +resource "aws_networkmanager_customer_gateway_association" "test" { + global_network_id = aws_networkmanager_global_network.test.id + customer_gateway_arn = aws_customer_gateway.test.arn + device_id = aws_networkmanager_device.test.id + + depends_on = [aws_networkmanager_transit_gateway_registration.test] +} +`, rName) +} diff --git a/internal/service/networkmanager/errors.go b/internal/service/networkmanager/errors.go index 19bfd542f89..a8ee8e1a4eb 100644 --- a/internal/service/networkmanager/errors.go +++ b/internal/service/networkmanager/errors.go @@ -8,6 +8,19 @@ import ( "github.com/aws/aws-sdk-go/service/networkmanager" ) +// resourceNotFoundExceptionResourceIDEquals returns true if the error matches all these conditions: +// * err is of type networkmanager.ResourceNotFoundException +// * ResourceNotFoundException.ResourceId equals resourceID +func resourceNotFoundExceptionResourceIDEquals(err error, resourceID string) bool { + var resourceNotFoundException *networkmanager.ResourceNotFoundException + + if errors.As(err, &resourceNotFoundException) && aws.StringValue(resourceNotFoundException.ResourceId) == resourceID { + return true + } + + return false +} + // validationExceptionMessageContains returns true if the error matches all these conditions: // * err is of type networkmanager.ValidationException // * ValidationException.Reason equals reason diff --git a/internal/service/networkmanager/global_network.go b/internal/service/networkmanager/global_network.go index 59d43b2aade..ef671d598f9 100644 --- a/internal/service/networkmanager/global_network.go +++ b/internal/service/networkmanager/global_network.go @@ -153,7 +153,7 @@ func resourceGlobalNetworkUpdate(ctx context.Context, d *schema.ResourceData, me func resourceGlobalNetworkDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*conns.AWSClient).NetworkManagerConn - tgwRegistrations, err := FindTransitGatewayRegistrations(ctx, conn, &networkmanager.GetTransitGatewayRegistrationsInput{ + cgwAssociations, err := FindCustomerGatewayAssociations(ctx, conn, &networkmanager.GetCustomerGatewayAssociationsInput{ GlobalNetworkId: aws.String(d.Id()), }) @@ -162,11 +162,35 @@ func resourceGlobalNetworkDelete(ctx context.Context, d *schema.ResourceData, me } if err != nil { - return diag.Errorf("error listing Transit Gateway Registrations (%s): %s", d.Id(), err) + return diag.Errorf("error listing Network Manager Customer Gateway Associations (%s): %s", d.Id(), err) } var diags diag.Diagnostics + for _, v := range cgwAssociations { + err := disassociateCustomerGateway(ctx, conn, d.Id(), aws.StringValue(v.CustomerGatewayArn), d.Timeout(schema.TimeoutDelete)) + + if err != nil { + diags = append(diags, diag.FromErr(err)...) + } + } + + if diags.HasError() { + return diags + } + + tgwRegistrations, err := FindTransitGatewayRegistrations(ctx, conn, &networkmanager.GetTransitGatewayRegistrationsInput{ + GlobalNetworkId: aws.String(d.Id()), + }) + + if tfresource.NotFound(err) { + err = nil + } + + if err != nil { + return diag.Errorf("error listing Network Manager Transit Gateway Registrations (%s): %s", d.Id(), err) + } + for _, v := range tgwRegistrations { err := deregisterTransitGateway(ctx, conn, d.Id(), aws.StringValue(v.TransitGatewayArn), d.Timeout(schema.TimeoutDelete)) diff --git a/website/docs/r/networkmanager_customer_gateway_association.html.markdown b/website/docs/r/networkmanager_customer_gateway_association.html.markdown new file mode 100644 index 00000000000..a44dfcd1bf8 --- /dev/null +++ b/website/docs/r/networkmanager_customer_gateway_association.html.markdown @@ -0,0 +1,80 @@ +--- +subcategory: "Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_customer_gateway_association" +description: |- + Associates a customer gateway with a device and optionally, with a link. +--- + +# Resource: aws_networkmanager_customer_gateway_association + +Associates a customer gateway with a device and optionally, with a link. +If you specify a link, it must be associated with the specified device. + +## Example Usage + +```terraform +resource "aws_networkmanager_global_network" "example" { + description = "example" +} + +resource "aws_networkmanager_site" "example" { + global_network_id = aws_networkmanager_global_network.example.id +} + +resource "aws_networkmanager_device" "example" { + global_network_id = aws_networkmanager_global_network.example.id + site_id = aws_networkmanager_site.example.id +} + +resource "aws_customer_gateway" "example" { + bgp_asn = 65000 + ip_address = "172.83.124.10" + type = "ipsec.1" +} + +resource "aws_ec2_transit_gateway" "example" {} + +resource "aws_vpn_connection" "example" { + customer_gateway_id = aws_customer_gateway.example.id + transit_gateway_id = aws_ec2_transit_gateway.example.id + type = aws_customer_gateway.example.type + static_routes_only = true +} + +resource "aws_networkmanager_transit_gateway_registration" "example" { + global_network_id = aws_networkmanager_global_network.example.id + transit_gateway_arn = aws_ec2_transit_gateway.example.arn + + depends_on = [aws_vpn_connection.example] +} + +resource "aws_networkmanager_customer_gateway_association" "example" { + global_network_id = aws_networkmanager_global_network.example.id + customer_gateway_arn = aws_customer_gateway.example.arn + device_id = aws_networkmanager_device.example.id + + depends_on = [aws_networkmanager_transit_gateway_registration.example] +} +``` + +## Argument Reference + +The following arguments are supported: + +* `customer_gateway_arn` - (Required) The Amazon Resource Name (ARN) of the customer gateway. +* `device_id` - (Required) The ID of the device. +* `global_network_id` - (Required) The ID of the global network. +* `link_id` - (Optional) The ID of the link. + +## Attributes Reference + +No additional attributes are exported. + +## Import + +`aws_networkmanager_customer_gateway_association` can be imported using the global network ID and customer gateway ARN, e.g. + +``` +$ terraform import aws_networkmanager_transit_gateway_registration.example global-network-0d47f6t230mz46dy4,arn:aws:ec2:us-west-2:123456789012:customer-gateway/cgw-123abc05e04123abc +``` From 11e52a28ce88fe2bc09ceb217d1603ae4f578f07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Prieto=20Ballester?= Date: Fri, 11 Mar 2022 18:20:57 +0100 Subject: [PATCH 132/229] Test added for Pre and Post login Banners --- internal/service/transfer/server_test.go | 40 ++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/internal/service/transfer/server_test.go b/internal/service/transfer/server_test.go index 37d2d0236a1..34dc4d229ab 100644 --- a/internal/service/transfer/server_test.go +++ b/internal/service/transfer/server_test.go @@ -51,8 +51,6 @@ func testAccServer_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "endpoint_type", "PUBLIC"), resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"), resource.TestCheckResourceAttr(resourceName, "function", ""), - resource.TestCheckResourceAttr(resourceName, "pre_display_banner", "Pre DisplayBanner"), - resource.TestCheckResourceAttr(resourceName, "post_display_banner", "Post Display Banner"), resource.TestCheckNoResourceAttr(resourceName, "host_key"), resource.TestCheckResourceAttrSet(resourceName, "host_key_fingerprint"), resource.TestCheckResourceAttr(resourceName, "identity_provider_type", "SERVICE_MANAGED"), @@ -83,7 +81,6 @@ func testAccServer_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "endpoint_type", "PUBLIC"), resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"), resource.TestCheckResourceAttr(resourceName, "function", ""), - resource.TestCheckResourceAttr(resourceName, "display_banners"), resource.TestCheckNoResourceAttr(resourceName, "host_key"), resource.TestCheckResourceAttrSet(resourceName, "host_key_fingerprint"), resource.TestCheckResourceAttr(resourceName, "identity_provider_type", "SERVICE_MANAGED"), @@ -944,6 +941,34 @@ func testAccServer_lambdaFunction(t *testing.T) { }) } +func TestAccTransferServer_DisplayBanners(t *testing.T) { + var conf transfer.DescribedServer + resourceName := "aws_transfer_server.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, transfer.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckServerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccServerDisplayBannersConfig(), + Check: resource.ComposeTestCheckFunc( + testAccCheckServerExists(resourceName, &conf), + resource.TestCheckResourceAttr(resourceName, "pre_display_banner", "This system is for the use of authorized users only"), + resource.TestCheckResourceAttr(resourceName, "post_display_banner", "This system is for the use of authorized users only"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"force_destroy"}, + }, + }, + }) +} + func testAccCheckServerExists(n string, v *transfer.DescribedServer) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -1197,6 +1222,15 @@ resource "aws_transfer_server" "test" {} ` } +func testAccServerDisplayBannersConfig() string { + return ` +resource "aws_transfer_server" "test" { + pre_display_banner = "This system is for the use of authorized users only" + post_display_banner = "This system is for the use of authorized users only" +} +` +} + func testAccServerDomainConfig() string { return ` resource "aws_transfer_server" "test" { From 36e63de60a4ccda8c04e6131c918871959fd2694 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Mar 2022 18:04:29 +0000 Subject: [PATCH 133/229] build(deps): bump github.com/aws/aws-sdk-go-v2/service/route53domains Bumps [github.com/aws/aws-sdk-go-v2/service/route53domains](https://github.com/aws/aws-sdk-go-v2) from 1.11.0 to 1.12.0. - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/main/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.11.0...v1.12.0) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go-v2/service/route53domains dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 358151c24bb..68e459bf4e7 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 github.com/aws/aws-sdk-go v1.43.9 github.com/aws/aws-sdk-go-v2 v1.15.0 - github.com/aws/aws-sdk-go-v2/service/route53domains v1.11.0 + github.com/aws/aws-sdk-go-v2/service/route53domains v1.12.0 github.com/beevik/etree v1.1.0 github.com/google/go-cmp v0.5.7 github.com/hashicorp/aws-cloudformation-resource-schema-sdk-go v0.16.0 diff --git a/go.sum b/go.sum index faaf8423f10..cd8c55ebf7d 100644 --- a/go.sum +++ b/go.sum @@ -67,7 +67,6 @@ github.com/aws/aws-sdk-go v1.42.18/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm github.com/aws/aws-sdk-go v1.42.52/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc= github.com/aws/aws-sdk-go v1.43.9 h1:k1S/29Bp2QD5ZopnGzIn0Sp63yyt3WH1JRE2OOU3Aig= github.com/aws/aws-sdk-go v1.43.9/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go-v2 v1.14.0/go.mod h1:ZA3Y8V0LrlWj63MQAnRHgKf/5QB//LSZCPNWlWrNGLU= github.com/aws/aws-sdk-go-v2 v1.15.0 h1:f9kWLNfyCzCB43eupDAk3/XgJ2EpgktiySD6leqs0js= github.com/aws/aws-sdk-go-v2 v1.15.0/go.mod h1:lJYcuZZEHWNIb6ugJjbQY1fykdoobWbOS7kJYb4APoI= github.com/aws/aws-sdk-go-v2/config v1.15.0 h1:cibCYF2c2uq0lsbu0Ggbg8RuGeiHCmXwUlTMS77CiK4= @@ -76,10 +75,8 @@ github.com/aws/aws-sdk-go-v2/credentials v1.10.0 h1:M/FFpf2w31F7xqJqJLgiM0mFpLOt github.com/aws/aws-sdk-go-v2/credentials v1.10.0/go.mod h1:HWJMr4ut5X+Lt/7epc7I6Llg5QIcoFHKAeIzw32t6EE= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.0 h1:gUlb+I7NwDtqJUIRcFYDiheYa97PdVHG/5Iz+SwdoHE= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.0/go.mod h1:prX26x9rmLwkEE1VVCelQOQgRN9sOVIssgowIJ270SE= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.5/go.mod h1:2hXc8ooJqF2nAznsbJQIn+7h851/bu8GVC80OVTTqf8= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.6 h1:xiGjGVQsem2cxoIX61uRGy+Jux2s9C/kKbTrWLdrU54= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.6/go.mod h1:SSPEdf9spsFgJyhjrXvawfpyzrXHBCUe+2eQ1CjC1Ak= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.3.0/go.mod h1:miRSv9l093jX/t/j+mBCaLqFHo9xKYzJ7DGm1BsGoJM= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.0 h1:bt3zw79tm209glISdMRCIVRCwvSDXxgAxh5KWe2qHkY= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.0/go.mod h1:viTrxhAuejD+LszDahzAE2x40YjYWhMqzHxv2ZiWaME= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.7 h1:QOMEP8jnO8sm0SX/4G7dbaIq2eEP2wcWEsF0jzrXLJc= @@ -88,13 +85,12 @@ github.com/aws/aws-sdk-go-v2/service/iam v1.18.0 h1:ZYpP40/QE7/R0zDxdrZyGGUijX26 github.com/aws/aws-sdk-go-v2/service/iam v1.18.0/go.mod h1:9wRsXAkRJ7qBWIDTFYa66Cx+oQJsPEnBYCPrinanpS8= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.0 h1:YQ3fTXACo7xeAqg0NiqcCmBOXJruUfh+4+O2qxF2EjQ= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.0/go.mod h1:R31ot6BgESRCIoxwfKtIHzZMo/vsZn2un81g9BJ4nmo= -github.com/aws/aws-sdk-go-v2/service/route53domains v1.11.0 h1:2zgdxEAnHQhwwqcZ7TioK2p4yVehUqvCiLKJghjn7s4= -github.com/aws/aws-sdk-go-v2/service/route53domains v1.11.0/go.mod h1:tq0XRh3gkEy4hGD5ssu1T5zSIxq8Ey5b+5JUv8SiiEs= +github.com/aws/aws-sdk-go-v2/service/route53domains v1.12.0 h1:PN0LQirFrjh9esAO80iZXo+asiTtLpjNCXpzZ+1BKCw= +github.com/aws/aws-sdk-go-v2/service/route53domains v1.12.0/go.mod h1:xzqCQW+Y6wn/4+9WVo3IPmnRTsN8Nwlw6cNUd6HVzqI= github.com/aws/aws-sdk-go-v2/service/sso v1.11.0 h1:gZLEXLH6NiU8Y52nRhK1jA+9oz7LZzBK242fi/ziXa4= github.com/aws/aws-sdk-go-v2/service/sso v1.11.0/go.mod h1:d1WcT0OjggjQCAdOkph8ijkr5sUwk1IH/VenOn7W1PU= github.com/aws/aws-sdk-go-v2/service/sts v1.16.0 h1:0+X/rJ2+DTBKWbUsn7WtF0JvNk/fRf928vkFsXkbbZs= github.com/aws/aws-sdk-go-v2/service/sts v1.16.0/go.mod h1:+8k4H2ASUZZXmjx/s3DFLo9tGBb44lkz3XcgfypJY7s= -github.com/aws/smithy-go v1.11.0/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= github.com/aws/smithy-go v1.11.1 h1:IQ+lPZVkSM3FRtyaDox41R8YS6iwPMYIreejOgPW49g= github.com/aws/smithy-go v1.11.1/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= From 4f045fe8811cee168c7bcefb7ad7efd3edf104d1 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 11 Mar 2022 13:34:50 -0500 Subject: [PATCH 134/229] Fix tfproviderdocs error 'import section code block text should contain resource name: aws_networkmanager_customer_gateway_association'. --- .../r/networkmanager_customer_gateway_association.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/networkmanager_customer_gateway_association.html.markdown b/website/docs/r/networkmanager_customer_gateway_association.html.markdown index a44dfcd1bf8..a3dbc642d02 100644 --- a/website/docs/r/networkmanager_customer_gateway_association.html.markdown +++ b/website/docs/r/networkmanager_customer_gateway_association.html.markdown @@ -76,5 +76,5 @@ No additional attributes are exported. `aws_networkmanager_customer_gateway_association` can be imported using the global network ID and customer gateway ARN, e.g. ``` -$ terraform import aws_networkmanager_transit_gateway_registration.example global-network-0d47f6t230mz46dy4,arn:aws:ec2:us-west-2:123456789012:customer-gateway/cgw-123abc05e04123abc +$ terraform import aws_networkmanager_customer_gateway_association.example global-network-0d47f6t230mz46dy4,arn:aws:ec2:us-west-2:123456789012:customer-gateway/cgw-123abc05e04123abc ``` From 63d7aaa1d870a0bb327d9358b2d9ec44128d931f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 11 Mar 2022 13:58:51 -0500 Subject: [PATCH 135/229] Add ARN validation. --- .../networkmanager/customer_gateway_association.go | 8 +++++--- .../networkmanager/transit_gateway_registration.go | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/internal/service/networkmanager/customer_gateway_association.go b/internal/service/networkmanager/customer_gateway_association.go index dbbc4db3d92..3412e99ed3f 100644 --- a/internal/service/networkmanager/customer_gateway_association.go +++ b/internal/service/networkmanager/customer_gateway_association.go @@ -15,6 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/internal/verify" ) func ResourceCustomerGatewayAssociation() *schema.Resource { @@ -34,9 +35,10 @@ func ResourceCustomerGatewayAssociation() *schema.Resource { Schema: map[string]*schema.Schema{ "customer_gateway_arn": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: verify.ValidARN, }, "device_id": { Type: schema.TypeString, diff --git a/internal/service/networkmanager/transit_gateway_registration.go b/internal/service/networkmanager/transit_gateway_registration.go index c3d9a9bc8cf..5a5f10103b9 100644 --- a/internal/service/networkmanager/transit_gateway_registration.go +++ b/internal/service/networkmanager/transit_gateway_registration.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/internal/verify" ) func ResourceTransitGatewayRegistration() *schema.Resource { @@ -40,9 +41,10 @@ func ResourceTransitGatewayRegistration() *schema.Resource { ForceNew: true, }, "transit_gateway_arn": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: verify.ValidARN, }, }, } From f821b8ab107a87324d6f1aedef245e1d8de8a0aa Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 11 Mar 2022 14:08:46 -0500 Subject: [PATCH 136/229] Correct acceptance test function names. --- .../customer_gateway_association_test.go | 14 +++++++------- .../transit_gateway_registration_test.go | 18 +++++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/internal/service/networkmanager/customer_gateway_association_test.go b/internal/service/networkmanager/customer_gateway_association_test.go index 15188a544cb..4468e0e0df4 100644 --- a/internal/service/networkmanager/customer_gateway_association_test.go +++ b/internal/service/networkmanager/customer_gateway_association_test.go @@ -16,11 +16,11 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -func TestAccNetworkManageCustomerGatewayAssociation_serial(t *testing.T) { +func TestAccNetworkManagerCustomerGatewayAssociation_serial(t *testing.T) { testCases := map[string]func(t *testing.T){ - "basic": testAccNetworkManageCustomerGatewayAssociation_basic, - "disappears": testAccNetworkManageCustomerGatewayAssociation_disappears, - "disappears_CustomerGateway": testAccNetworkManageCustomerGatewayAssociation_disappears_CustomerGateway, + "basic": testAccNetworkManagerCustomerGatewayAssociation_basic, + "disappears": testAccNetworkManagerCustomerGatewayAssociation_disappears, + "disappears_CustomerGateway": testAccNetworkManagerCustomerGatewayAssociation_disappears_CustomerGateway, } for name, tc := range testCases { @@ -31,7 +31,7 @@ func TestAccNetworkManageCustomerGatewayAssociation_serial(t *testing.T) { } } -func testAccNetworkManageCustomerGatewayAssociation_basic(t *testing.T) { +func testAccNetworkManagerCustomerGatewayAssociation_basic(t *testing.T) { resourceName := "aws_networkmanager_customer_gateway_association.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -56,7 +56,7 @@ func testAccNetworkManageCustomerGatewayAssociation_basic(t *testing.T) { }) } -func testAccNetworkManageCustomerGatewayAssociation_disappears(t *testing.T) { +func testAccNetworkManagerCustomerGatewayAssociation_disappears(t *testing.T) { resourceName := "aws_networkmanager_customer_gateway_association.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -78,7 +78,7 @@ func testAccNetworkManageCustomerGatewayAssociation_disappears(t *testing.T) { }) } -func testAccNetworkManageCustomerGatewayAssociation_disappears_CustomerGateway(t *testing.T) { +func testAccNetworkManagerCustomerGatewayAssociation_disappears_CustomerGateway(t *testing.T) { resourceName := "aws_networkmanager_customer_gateway_association.test" vpnConnectionResourceName := "aws_vpn_connection.test" customerGatewayResourceName := "aws_customer_gateway.test" diff --git a/internal/service/networkmanager/transit_gateway_registration_test.go b/internal/service/networkmanager/transit_gateway_registration_test.go index 30019664a87..a0713612118 100644 --- a/internal/service/networkmanager/transit_gateway_registration_test.go +++ b/internal/service/networkmanager/transit_gateway_registration_test.go @@ -17,12 +17,12 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -func TestAccNetworkManageTransitGatewayRegistration_serial(t *testing.T) { +func TestAccNetworkManagerTransitGatewayRegistration_serial(t *testing.T) { testCases := map[string]func(t *testing.T){ - "basic": testAccNetworkManageTransitGatewayRegistration_basic, - "disappears": testAccNetworkManageTransitGatewayRegistration_disappears, - "disappears_TransitGateway": testAccNetworkManageTransitGatewayRegistration_disappears_TransitGateway, - "crossRegion": testAccNetworkManageTransitGatewayRegistration_crossRegion, + "basic": testAccNetworkManagerTransitGatewayRegistration_basic, + "disappears": testAccNetworkManagerTransitGatewayRegistration_disappears, + "disappears_TransitGateway": testAccNetworkManagerTransitGatewayRegistration_disappears_TransitGateway, + "crossRegion": testAccNetworkManagerTransitGatewayRegistration_crossRegion, } for name, tc := range testCases { @@ -33,7 +33,7 @@ func TestAccNetworkManageTransitGatewayRegistration_serial(t *testing.T) { } } -func testAccNetworkManageTransitGatewayRegistration_basic(t *testing.T) { +func testAccNetworkManagerTransitGatewayRegistration_basic(t *testing.T) { resourceName := "aws_networkmanager_transit_gateway_registration.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -58,7 +58,7 @@ func testAccNetworkManageTransitGatewayRegistration_basic(t *testing.T) { }) } -func testAccNetworkManageTransitGatewayRegistration_disappears(t *testing.T) { +func testAccNetworkManagerTransitGatewayRegistration_disappears(t *testing.T) { resourceName := "aws_networkmanager_transit_gateway_registration.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -80,7 +80,7 @@ func testAccNetworkManageTransitGatewayRegistration_disappears(t *testing.T) { }) } -func testAccNetworkManageTransitGatewayRegistration_disappears_TransitGateway(t *testing.T) { +func testAccNetworkManagerTransitGatewayRegistration_disappears_TransitGateway(t *testing.T) { resourceName := "aws_networkmanager_transit_gateway_registration.test" transitGatewayResourceName := "aws_ec2_transit_gateway.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -103,7 +103,7 @@ func testAccNetworkManageTransitGatewayRegistration_disappears_TransitGateway(t }) } -func testAccNetworkManageTransitGatewayRegistration_crossRegion(t *testing.T) { +func testAccNetworkManagerTransitGatewayRegistration_crossRegion(t *testing.T) { resourceName := "aws_networkmanager_transit_gateway_registration.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) var providers []*schema.Provider From 452edb821ba3a0e571765ef176dc718249f67556 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 11 Mar 2022 14:36:41 -0500 Subject: [PATCH 137/229] r/aws_ec2_transit_gateway_connect_peer: Add 'arn' attribute. --- .changelog/13251.txt | 4 ++++ .../service/ec2/transit_gateway_connect_peer.go | 14 ++++++++++++++ .../ec2_transit_gateway_connect_peer.html.markdown | 3 ++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/.changelog/13251.txt b/.changelog/13251.txt index 25718c95924..012a2fc0d4c 100644 --- a/.changelog/13251.txt +++ b/.changelog/13251.txt @@ -56,4 +56,8 @@ aws_networkmanager_link ```release-note:new-data-source aws_networkmanager_links +``` + +```release-note:enhancement +resource/aws_ec2_transit_gateway_connect_peer: Add `arn` attribute ``` \ No newline at end of file diff --git a/internal/service/ec2/transit_gateway_connect_peer.go b/internal/service/ec2/transit_gateway_connect_peer.go index e911f553f44..f99d6fba347 100644 --- a/internal/service/ec2/transit_gateway_connect_peer.go +++ b/internal/service/ec2/transit_gateway_connect_peer.go @@ -2,12 +2,14 @@ package ec2 import ( "context" + "fmt" "log" "regexp" "strconv" "time" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" @@ -39,6 +41,10 @@ func ResourceTransitGatewayConnectPeer() *schema.Resource { CustomizeDiff: verify.SetTagsDiff, Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, "bgp_asn": { Type: schema.TypeString, Optional: true, @@ -152,6 +158,14 @@ func resourceTransitGatewayConnectPeerRead(ctx context.Context, d *schema.Resour return diag.Errorf("error reading EC2 Transit Gateway Connect Peer (%s): %s", d.Id(), err) } + arn := arn.ARN{ + Partition: meta.(*conns.AWSClient).Partition, + Service: ec2.ServiceName, + Region: meta.(*conns.AWSClient).Region, + AccountID: meta.(*conns.AWSClient).AccountID, + Resource: fmt.Sprintf("transit-gateway-connect-peer/%s", d.Id()), + }.String() + d.Set("arn", arn) d.Set("bgp_asn", strconv.FormatInt(aws.Int64Value(transitGatewayConnectPeer.ConnectPeerConfiguration.BgpConfigurations[0].PeerAsn), 10)) d.Set("inside_cidr_blocks", aws.StringValueSlice(transitGatewayConnectPeer.ConnectPeerConfiguration.InsideCidrBlocks)) d.Set("peer_address", transitGatewayConnectPeer.ConnectPeerConfiguration.PeerAddress) diff --git a/website/docs/r/ec2_transit_gateway_connect_peer.html.markdown b/website/docs/r/ec2_transit_gateway_connect_peer.html.markdown index 3a523ee1ba8..0ab8f4566f1 100644 --- a/website/docs/r/ec2_transit_gateway_connect_peer.html.markdown +++ b/website/docs/r/ec2_transit_gateway_connect_peer.html.markdown @@ -40,7 +40,8 @@ The following arguments are supported: In addition to all arguments above, the following attributes are exported: -* `id` - EC2 Transit Gateway Attachment identifier +* `id` - EC2 Transit Gateway Connect Peer identifier +* `arn` - EC2 Transit Gateway Connect Peer ARN * `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](https://www.terraform.io/docs/providers/aws/index.html#default_tags-configuration-block). ## Timeouts From c553028d8a6d194ba0e5fb15ce5fee72557b965e Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 11 Mar 2022 14:37:23 -0500 Subject: [PATCH 138/229] d/aws_ec2_transit_gateway_connect_peer: Add 'arn' attribute. --- .changelog/13251.txt | 6 +++++- .../ec2/transit_gateway_connect_peer_data_source.go | 11 +++++++++++ .../transit_gateway_connect_peer_data_source_test.go | 2 ++ .../d/ec2_transit_gateway_connect_peer.html.markdown | 1 + 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/.changelog/13251.txt b/.changelog/13251.txt index 012a2fc0d4c..e2dc2dab332 100644 --- a/.changelog/13251.txt +++ b/.changelog/13251.txt @@ -60,4 +60,8 @@ aws_networkmanager_links ```release-note:enhancement resource/aws_ec2_transit_gateway_connect_peer: Add `arn` attribute -``` \ No newline at end of file +``` + +```release-note:enhancement +data-source/aws_ec2_transit_gateway_connect_peer: Add `arn` attribute +``` diff --git a/internal/service/ec2/transit_gateway_connect_peer_data_source.go b/internal/service/ec2/transit_gateway_connect_peer_data_source.go index 89ae6a8a75f..ce937fddc3f 100644 --- a/internal/service/ec2/transit_gateway_connect_peer_data_source.go +++ b/internal/service/ec2/transit_gateway_connect_peer_data_source.go @@ -2,9 +2,11 @@ package ec2 import ( "context" + "fmt" "strconv" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/arn" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -71,6 +73,15 @@ func dataSourceTransitGatewayConnectPeerRead(ctx context.Context, d *schema.Reso } d.SetId(aws.StringValue(transitGatewayConnectPeer.TransitGatewayConnectPeerId)) + + arn := arn.ARN{ + Partition: meta.(*conns.AWSClient).Partition, + Service: ec2.ServiceName, + Region: meta.(*conns.AWSClient).Region, + AccountID: meta.(*conns.AWSClient).AccountID, + Resource: fmt.Sprintf("transit-gateway-connect-peer/%s", d.Id()), + }.String() + d.Set("arn", arn) d.Set("bgp_asn", strconv.FormatInt(aws.Int64Value(transitGatewayConnectPeer.ConnectPeerConfiguration.BgpConfigurations[0].PeerAsn), 10)) d.Set("inside_cidr_blocks", aws.StringValueSlice(transitGatewayConnectPeer.ConnectPeerConfiguration.InsideCidrBlocks)) d.Set("peer_address", transitGatewayConnectPeer.ConnectPeerConfiguration.PeerAddress) diff --git a/internal/service/ec2/transit_gateway_connect_peer_data_source_test.go b/internal/service/ec2/transit_gateway_connect_peer_data_source_test.go index bed5fdbe73f..1c6a802101e 100644 --- a/internal/service/ec2/transit_gateway_connect_peer_data_source_test.go +++ b/internal/service/ec2/transit_gateway_connect_peer_data_source_test.go @@ -24,6 +24,7 @@ func testAccTransitGatewayConnectPeerDataSource_Filter(t *testing.T) { { Config: testAccTransitGatewayConnectPeerFilterDataSourceConfig(rName), Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"), resource.TestCheckResourceAttrPair(dataSourceName, "bgp_asn", resourceName, "bgp_asn"), resource.TestCheckResourceAttrPair(dataSourceName, "inside_cidr_blocks.#", resourceName, "inside_cidr_blocks.#"), resource.TestCheckResourceAttrPair(dataSourceName, "peer_address", resourceName, "peer_address"), @@ -51,6 +52,7 @@ func testAccTransitGatewayConnectPeerDataSource_ID(t *testing.T) { { Config: testAccTransitGatewayConnectPeerIDDataSourceConfig(rName), Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"), resource.TestCheckResourceAttrPair(dataSourceName, "bgp_asn", resourceName, "bgp_asn"), resource.TestCheckResourceAttrPair(dataSourceName, "inside_cidr_blocks.#", resourceName, "inside_cidr_blocks.#"), resource.TestCheckResourceAttrPair(dataSourceName, "peer_address", resourceName, "peer_address"), diff --git a/website/docs/d/ec2_transit_gateway_connect_peer.html.markdown b/website/docs/d/ec2_transit_gateway_connect_peer.html.markdown index e8c68bc5288..3c58f0799ac 100644 --- a/website/docs/d/ec2_transit_gateway_connect_peer.html.markdown +++ b/website/docs/d/ec2_transit_gateway_connect_peer.html.markdown @@ -47,6 +47,7 @@ The following arguments are supported: In addition to all arguments above, the following attributes are exported: +* `arn` - EC2 Transit Gateway Connect Peer ARN * `bgp_asn` - The BGP ASN number assigned customer device * `inside_cidr_blocks` - The CIDR blocks that will be used for addressing within the tunnel. * `peer_address` - The IP addressed assigned to customer device, which is used as tunnel endpoint From b5e0471013460b0dcf6643e4a568beab26307179 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 11 Mar 2022 15:39:40 -0500 Subject: [PATCH 139/229] r/aws_networkmanager_transit_gateway_connect_peer_association: New resource. Acceptance test output: % make testacc TESTARGS='-run=TestAccNetworkManagerTransitGatewayConnectPeerAssociation_serial' PKG=networkmanager ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/networkmanager/... -v -count 1 -parallel 20 -run=TestAccNetworkManagerTransitGatewayConnectPeerAssociation_serial -timeout 180m === RUN TestAccNetworkManagerTransitGatewayConnectPeerAssociation_serial === RUN TestAccNetworkManagerTransitGatewayConnectPeerAssociation_serial/basic === RUN TestAccNetworkManagerTransitGatewayConnectPeerAssociation_serial/disappears === RUN TestAccNetworkManagerTransitGatewayConnectPeerAssociation_serial/disappears_ConnectPeer --- PASS: TestAccNetworkManagerTransitGatewayConnectPeerAssociation_serial (2520.30s) --- PASS: TestAccNetworkManagerTransitGatewayConnectPeerAssociation_serial/basic (850.86s) --- PASS: TestAccNetworkManagerTransitGatewayConnectPeerAssociation_serial/disappears (837.86s) --- PASS: TestAccNetworkManagerTransitGatewayConnectPeerAssociation_serial/disappears_ConnectPeer (831.59s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 2523.822s --- .changelog/13251.txt | 4 + internal/provider/provider.go | 15 +- .../service/networkmanager/global_network.go | 110 ++++-- ...ransit_gateway_connect_peer_association.go | 312 ++++++++++++++++++ ...t_gateway_connect_peer_association_test.go | 259 +++++++++++++++ ...way_connect_peer_association.html.markdown | 43 +++ 6 files changed, 707 insertions(+), 36 deletions(-) create mode 100644 internal/service/networkmanager/transit_gateway_connect_peer_association.go create mode 100644 internal/service/networkmanager/transit_gateway_connect_peer_association_test.go create mode 100644 website/docs/r/networkmanager_transit_gateway_connect_peer_association.html.markdown diff --git a/.changelog/13251.txt b/.changelog/13251.txt index e2dc2dab332..e806d5f73f3 100644 --- a/.changelog/13251.txt +++ b/.changelog/13251.txt @@ -26,6 +26,10 @@ aws_networkmanager_link_association aws_networkmanager_customer_gateway_association ``` +```release-note:new-resource +aws_networkmanager_transit_gateway_connect_peer_association +``` + ```release-note:new-data-source aws_networkmanager_global_network ``` diff --git a/internal/provider/provider.go b/internal/provider/provider.go index dea1046204f..a13352293c1 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1586,13 +1586,14 @@ func Provider() *schema.Provider { "aws_networkfirewall_resource_policy": networkfirewall.ResourceResourcePolicy(), "aws_networkfirewall_rule_group": networkfirewall.ResourceRuleGroup(), - "aws_networkmanager_customer_gateway_association": networkmanager.ResourceCustomerGatewayAssociation(), - "aws_networkmanager_device": networkmanager.ResourceDevice(), - "aws_networkmanager_global_network": networkmanager.ResourceGlobalNetwork(), - "aws_networkmanager_link": networkmanager.ResourceLink(), - "aws_networkmanager_link_association": networkmanager.ResourceLinkAssociation(), - "aws_networkmanager_site": networkmanager.ResourceSite(), - "aws_networkmanager_transit_gateway_registration": networkmanager.ResourceTransitGatewayRegistration(), + "aws_networkmanager_customer_gateway_association": networkmanager.ResourceCustomerGatewayAssociation(), + "aws_networkmanager_device": networkmanager.ResourceDevice(), + "aws_networkmanager_global_network": networkmanager.ResourceGlobalNetwork(), + "aws_networkmanager_link": networkmanager.ResourceLink(), + "aws_networkmanager_link_association": networkmanager.ResourceLinkAssociation(), + "aws_networkmanager_site": networkmanager.ResourceSite(), + "aws_networkmanager_transit_gateway_connect_peer_association": networkmanager.ResourceTransitGatewayConnectPeerAssociation(), + "aws_networkmanager_transit_gateway_registration": networkmanager.ResourceTransitGatewayRegistration(), "aws_opsworks_application": opsworks.ResourceApplication(), "aws_opsworks_custom_layer": opsworks.ResourceCustomLayer(), diff --git a/internal/service/networkmanager/global_network.go b/internal/service/networkmanager/global_network.go index ef671d598f9..37d88fea130 100644 --- a/internal/service/networkmanager/global_network.go +++ b/internal/service/networkmanager/global_network.go @@ -153,8 +153,52 @@ func resourceGlobalNetworkUpdate(ctx context.Context, d *schema.ResourceData, me func resourceGlobalNetworkDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*conns.AWSClient).NetworkManagerConn - cgwAssociations, err := FindCustomerGatewayAssociations(ctx, conn, &networkmanager.GetCustomerGatewayAssociationsInput{ - GlobalNetworkId: aws.String(d.Id()), + if diags := disassociateCustomerGateways(ctx, conn, d.Id(), d.Timeout(schema.TimeoutDelete)); diags.HasError() { + return diags + } + + if diags := disassociateTransitGatewayConnectPeers(ctx, conn, d.Id(), d.Timeout(schema.TimeoutDelete)); diags.HasError() { + return diags + } + + if diags := deregisterTransitGateways(ctx, conn, d.Id(), d.Timeout(schema.TimeoutDelete)); diags.HasError() { + return diags + } + + log.Printf("[DEBUG] Deleting Network Manager Global Network: %s", d.Id()) + _, err := tfresource.RetryWhenContext(ctx, globalNetworkValidationExceptionTimeout, + func() (interface{}, error) { + return conn.DeleteGlobalNetworkWithContext(ctx, &networkmanager.DeleteGlobalNetworkInput{ + GlobalNetworkId: aws.String(d.Id()), + }) + }, + func(err error) (bool, error) { + if tfawserr.ErrMessageContains(err, networkmanager.ErrCodeValidationException, "cannot be deleted due to existing devices, sites, or links") { + return true, err + } + + return false, err + }, + ) + + if tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeResourceNotFoundException) { + return nil + } + + if err != nil { + return diag.Errorf("error deleting Network Manager Global Network (%s): %s", d.Id(), err) + } + + if _, err := waitGlobalNetworkDeleted(ctx, conn, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil { + return diag.Errorf("error waiting for Network Manager Global Network (%s) delete: %s", d.Id(), err) + } + + return nil +} + +func deregisterTransitGateways(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID string, timeout time.Duration) diag.Diagnostics { + output, err := FindTransitGatewayRegistrations(ctx, conn, &networkmanager.GetTransitGatewayRegistrationsInput{ + GlobalNetworkId: aws.String(globalNetworkID), }) if tfresource.NotFound(err) { @@ -162,13 +206,13 @@ func resourceGlobalNetworkDelete(ctx context.Context, d *schema.ResourceData, me } if err != nil { - return diag.Errorf("error listing Network Manager Customer Gateway Associations (%s): %s", d.Id(), err) + return diag.Errorf("error listing Network Manager Transit Gateway Registrations (%s): %s", globalNetworkID, err) } var diags diag.Diagnostics - for _, v := range cgwAssociations { - err := disassociateCustomerGateway(ctx, conn, d.Id(), aws.StringValue(v.CustomerGatewayArn), d.Timeout(schema.TimeoutDelete)) + for _, v := range output { + err := deregisterTransitGateway(ctx, conn, globalNetworkID, aws.StringValue(v.TransitGatewayArn), timeout) if err != nil { diags = append(diags, diag.FromErr(err)...) @@ -179,8 +223,12 @@ func resourceGlobalNetworkDelete(ctx context.Context, d *schema.ResourceData, me return diags } - tgwRegistrations, err := FindTransitGatewayRegistrations(ctx, conn, &networkmanager.GetTransitGatewayRegistrationsInput{ - GlobalNetworkId: aws.String(d.Id()), + return nil +} + +func disassociateCustomerGateways(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID string, timeout time.Duration) diag.Diagnostics { + output, err := FindCustomerGatewayAssociations(ctx, conn, &networkmanager.GetCustomerGatewayAssociationsInput{ + GlobalNetworkId: aws.String(globalNetworkID), }) if tfresource.NotFound(err) { @@ -188,11 +236,13 @@ func resourceGlobalNetworkDelete(ctx context.Context, d *schema.ResourceData, me } if err != nil { - return diag.Errorf("error listing Network Manager Transit Gateway Registrations (%s): %s", d.Id(), err) + return diag.Errorf("error listing Network Manager Customer Gateway Associations (%s): %s", globalNetworkID, err) } - for _, v := range tgwRegistrations { - err := deregisterTransitGateway(ctx, conn, d.Id(), aws.StringValue(v.TransitGatewayArn), d.Timeout(schema.TimeoutDelete)) + var diags diag.Diagnostics + + for _, v := range output { + err := disassociateCustomerGateway(ctx, conn, globalNetworkID, aws.StringValue(v.CustomerGatewayArn), timeout) if err != nil { diags = append(diags, diag.FromErr(err)...) @@ -203,32 +253,34 @@ func resourceGlobalNetworkDelete(ctx context.Context, d *schema.ResourceData, me return diags } - log.Printf("[DEBUG] Deleting Network Manager Global Network: %s", d.Id()) - _, err = tfresource.RetryWhenContext(ctx, globalNetworkValidationExceptionTimeout, - func() (interface{}, error) { - return conn.DeleteGlobalNetworkWithContext(ctx, &networkmanager.DeleteGlobalNetworkInput{ - GlobalNetworkId: aws.String(d.Id()), - }) - }, - func(err error) (bool, error) { - if tfawserr.ErrMessageContains(err, networkmanager.ErrCodeValidationException, "cannot be deleted due to existing devices, sites, or links") { - return true, err - } + return nil +} - return false, err - }, - ) +func disassociateTransitGatewayConnectPeers(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID string, timeout time.Duration) diag.Diagnostics { + output, err := FindTransitGatewayConnectPeerAssociations(ctx, conn, &networkmanager.GetTransitGatewayConnectPeerAssociationsInput{ + GlobalNetworkId: aws.String(globalNetworkID), + }) - if tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeResourceNotFoundException) { - return nil + if tfresource.NotFound(err) { + err = nil } if err != nil { - return diag.Errorf("error deleting Network Manager Global Network (%s): %s", d.Id(), err) + return diag.Errorf("error listing Network Manager Transit Gateway Connect Peer Associations (%s): %s", globalNetworkID, err) } - if _, err := waitGlobalNetworkDeleted(ctx, conn, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil { - return diag.Errorf("error waiting for Network Manager Global Network (%s) delete: %s", d.Id(), err) + var diags diag.Diagnostics + + for _, v := range output { + err := disassociateTransitGatewayConnectPeer(ctx, conn, globalNetworkID, aws.StringValue(v.TransitGatewayConnectPeerArn), timeout) + + if err != nil { + diags = append(diags, diag.FromErr(err)...) + } + } + + if diags.HasError() { + return diags } return nil diff --git a/internal/service/networkmanager/transit_gateway_connect_peer_association.go b/internal/service/networkmanager/transit_gateway_connect_peer_association.go new file mode 100644 index 00000000000..94ae13d29c7 --- /dev/null +++ b/internal/service/networkmanager/transit_gateway_connect_peer_association.go @@ -0,0 +1,312 @@ +package networkmanager + +import ( + "context" + "fmt" + "log" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/internal/verify" +) + +func ResourceTransitGatewayConnectPeerAssociation() *schema.Resource { + return &schema.Resource{ + CreateWithoutTimeout: resourceTransitGatewayConnectPeerAssociationCreate, + ReadWithoutTimeout: resourceTransitGatewayConnectPeerAssociationRead, + DeleteWithoutTimeout: resourceTransitGatewayConnectPeerAssociationDelete, + + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "device_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "global_network_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "link_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "transit_gateway_connect_peer_arn": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: verify.ValidARN, + }, + }, + } +} + +func resourceTransitGatewayConnectPeerAssociationCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + globalNetworkID := d.Get("global_network_id").(string) + connectPeerARN := d.Get("transit_gateway_connect_peer_arn").(string) + id := TransitGatewayConnectPeerAssociationCreateResourceID(globalNetworkID, connectPeerARN) + input := &networkmanager.AssociateTransitGatewayConnectPeerInput{ + DeviceId: aws.String(d.Get("device_id").(string)), + GlobalNetworkId: aws.String(globalNetworkID), + TransitGatewayConnectPeerArn: aws.String(connectPeerARN), + } + + if v, ok := d.GetOk("link_id"); ok { + input.LinkId = aws.String(v.(string)) + } + + log.Printf("[DEBUG] Creating Network Manager Transit Gateway Connect Peer Association: %s", input) + _, err := conn.AssociateTransitGatewayConnectPeerWithContext(ctx, input) + + if err != nil { + return diag.Errorf("error creating Network Manager Transit Gateway Connect Peer Association (%s): %s", id, err) + } + + d.SetId(id) + + if _, err := waitTransitGatewayConnectPeerAssociationCreated(ctx, conn, globalNetworkID, connectPeerARN, d.Timeout(schema.TimeoutCreate)); err != nil { + return diag.Errorf("error waiting for Network Manager Transit Gateway Connect Peer Association (%s) create: %s", d.Id(), err) + } + + return resourceTransitGatewayConnectPeerAssociationRead(ctx, d, meta) +} + +func resourceTransitGatewayConnectPeerAssociationRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + globalNetworkID, connectPeerARN, err := TransitGatewayConnectPeerAssociationParseResourceID(d.Id()) + + if err != nil { + return diag.FromErr(err) + } + + output, err := FindTransitGatewayConnectPeerAssociationByTwoPartKey(ctx, conn, globalNetworkID, connectPeerARN) + + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Network Manager Transit Gateway Connect Peer Association %s not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return diag.Errorf("error reading Network Manager Transit Gateway Connect Peer Association (%s): %s", d.Id(), err) + } + + d.Set("device_id", output.DeviceId) + d.Set("global_network_id", output.GlobalNetworkId) + d.Set("link_id", output.LinkId) + d.Set("transit_gateway_connect_peer_arn", output.TransitGatewayConnectPeerArn) + + return nil +} + +func resourceTransitGatewayConnectPeerAssociationDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + globalNetworkID, connectPeerARN, err := TransitGatewayConnectPeerAssociationParseResourceID(d.Id()) + + if err != nil { + return diag.FromErr(err) + } + + err = disassociateTransitGatewayConnectPeer(ctx, conn, globalNetworkID, connectPeerARN, d.Timeout(schema.TimeoutDelete)) + + if err != nil { + return diag.FromErr(err) + } + + return nil +} + +func disassociateTransitGatewayConnectPeer(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, connectPeerARN string, timeout time.Duration) error { + id := TransitGatewayConnectPeerAssociationCreateResourceID(globalNetworkID, connectPeerARN) + + log.Printf("[DEBUG] Deleting Network Manager Transit Gateway Connect Peer Association: %s", id) + _, err := conn.DisassociateTransitGatewayConnectPeerWithContext(ctx, &networkmanager.DisassociateTransitGatewayConnectPeerInput{ + GlobalNetworkId: aws.String(globalNetworkID), + TransitGatewayConnectPeerArn: aws.String(connectPeerARN), + }) + + if globalNetworkIDNotFoundError(err) || tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeResourceNotFoundException) { + return nil + } + + if err != nil { + return fmt.Errorf("error deleting Network Manager Transit Gateway Connect Peer Association (%s): %w", id, err) + } + + if _, err := waitTransitGatewayConnectPeerAssociationDeleted(ctx, conn, globalNetworkID, connectPeerARN, timeout); err != nil { + return fmt.Errorf("error waiting for Network Manager Transit Gateway Connect Peer Association (%s) delete: %w", id, err) + } + + return nil +} + +func FindTransitGatewayConnectPeerAssociation(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.GetTransitGatewayConnectPeerAssociationsInput) (*networkmanager.TransitGatewayConnectPeerAssociation, error) { + output, err := FindTransitGatewayConnectPeerAssociations(ctx, conn, input) + + if err != nil { + return nil, err + } + + if len(output) == 0 || output[0] == nil || output[0].State == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } + + return output[0], nil +} + +func FindTransitGatewayConnectPeerAssociations(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.GetTransitGatewayConnectPeerAssociationsInput) ([]*networkmanager.TransitGatewayConnectPeerAssociation, error) { + var output []*networkmanager.TransitGatewayConnectPeerAssociation + + err := conn.GetTransitGatewayConnectPeerAssociationsPagesWithContext(ctx, input, func(page *networkmanager.GetTransitGatewayConnectPeerAssociationsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.TransitGatewayConnectPeerAssociations { + if v == nil { + continue + } + + output = append(output, v) + } + + return !lastPage + }) + + if globalNetworkIDNotFoundError(err) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + return output, nil +} + +func FindTransitGatewayConnectPeerAssociationByTwoPartKey(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, connectPeerARN string) (*networkmanager.TransitGatewayConnectPeerAssociation, error) { + input := &networkmanager.GetTransitGatewayConnectPeerAssociationsInput{ + GlobalNetworkId: aws.String(globalNetworkID), + TransitGatewayConnectPeerArns: aws.StringSlice([]string{connectPeerARN}), + } + + output, err := FindTransitGatewayConnectPeerAssociation(ctx, conn, input) + + if err != nil { + return nil, err + } + + if state := aws.StringValue(output.State); state == networkmanager.TransitGatewayConnectPeerAssociationStateDeleted { + return nil, &resource.NotFoundError{ + Message: state, + LastRequest: input, + } + } + + // Eventual consistency check. + if aws.StringValue(output.GlobalNetworkId) != globalNetworkID || aws.StringValue(output.TransitGatewayConnectPeerArn) != connectPeerARN { + return nil, &resource.NotFoundError{ + LastRequest: input, + } + } + + return output, nil +} + +func statusTransitGatewayConnectPeerAssociationState(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, connectPeerARN string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + output, err := FindTransitGatewayConnectPeerAssociationByTwoPartKey(ctx, conn, globalNetworkID, connectPeerARN) + + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return output, aws.StringValue(output.State), nil + } +} + +func waitTransitGatewayConnectPeerAssociationCreated(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, connectPeerARN string, timeout time.Duration) (*networkmanager.TransitGatewayConnectPeerAssociation, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.TransitGatewayConnectPeerAssociationStatePending}, + Target: []string{networkmanager.TransitGatewayConnectPeerAssociationStateAvailable}, + Timeout: timeout, + Refresh: statusTransitGatewayConnectPeerAssociationState(ctx, conn, globalNetworkID, connectPeerARN), + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*networkmanager.TransitGatewayConnectPeerAssociation); ok { + return output, err + } + + return nil, err +} + +func waitTransitGatewayConnectPeerAssociationDeleted(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, connectPeerARN string, timeout time.Duration) (*networkmanager.TransitGatewayConnectPeerAssociation, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.TransitGatewayConnectPeerAssociationStateAvailable, networkmanager.TransitGatewayConnectPeerAssociationStateDeleting}, + Target: []string{}, + Timeout: timeout, + Refresh: statusTransitGatewayConnectPeerAssociationState(ctx, conn, globalNetworkID, connectPeerARN), + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*networkmanager.TransitGatewayConnectPeerAssociation); ok { + return output, err + } + + return nil, err +} + +const transitGatewayConnectPeerAssociationIDSeparator = "," + +func TransitGatewayConnectPeerAssociationCreateResourceID(globalNetworkID, connectPeerARN string) string { + parts := []string{globalNetworkID, connectPeerARN} + id := strings.Join(parts, transitGatewayConnectPeerAssociationIDSeparator) + + return id +} + +func TransitGatewayConnectPeerAssociationParseResourceID(id string) (string, string, error) { + parts := strings.Split(id, transitGatewayConnectPeerAssociationIDSeparator) + + if len(parts) == 2 && parts[0] != "" && parts[1] != "" { + return parts[0], parts[1], nil + } + + return "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected GLOBAL-NETWORK-ID%[2]sCONNECT-PEER-ARN", id, transitGatewayConnectPeerAssociationIDSeparator) +} diff --git a/internal/service/networkmanager/transit_gateway_connect_peer_association_test.go b/internal/service/networkmanager/transit_gateway_connect_peer_association_test.go new file mode 100644 index 00000000000..26e055cb27c --- /dev/null +++ b/internal/service/networkmanager/transit_gateway_connect_peer_association_test.go @@ -0,0 +1,259 @@ +package networkmanager_test + +import ( + "context" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/networkmanager" + 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" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tfec2 "github.com/hashicorp/terraform-provider-aws/internal/service/ec2" + tfnetworkmanager "github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" +) + +func TestAccNetworkManagerTransitGatewayConnectPeerAssociation_serial(t *testing.T) { + testCases := map[string]func(t *testing.T){ + "basic": testAccNetworkManagerTransitGatewayConnectPeerAssociation_basic, + "disappears": testAccNetworkManagerTransitGatewayConnectPeerAssociation_disappears, + "disappears_ConnectPeer": testAccNetworkManagerTransitGatewayConnectPeerAssociation_disappears_ConnectPeer, + } + + for name, tc := range testCases { + tc := tc + t.Run(name, func(t *testing.T) { + tc(t) + }) + } +} + +func testAccNetworkManagerTransitGatewayConnectPeerAssociation_basic(t *testing.T) { + resourceName := "aws_networkmanager_transit_gateway_connect_peer_association.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckTransitGatewayConnectPeerAssociationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTransitGatewayConnectPeerAssociationConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckTransitGatewayConnectPeerAssociationExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccNetworkManagerTransitGatewayConnectPeerAssociation_disappears(t *testing.T) { + resourceName := "aws_networkmanager_transit_gateway_connect_peer_association.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckTransitGatewayConnectPeerAssociationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTransitGatewayConnectPeerAssociationConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckTransitGatewayConnectPeerAssociationExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfnetworkmanager.ResourceTransitGatewayConnectPeerAssociation(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccNetworkManagerTransitGatewayConnectPeerAssociation_disappears_ConnectPeer(t *testing.T) { + resourceName := "aws_networkmanager_transit_gateway_connect_peer_association.test" + connetPeerResourceName := "aws_ec2_transit_gateway_connect_peer.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckTransitGatewayConnectPeerAssociationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTransitGatewayConnectPeerAssociationConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckTransitGatewayConnectPeerAssociationExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfec2.ResourceTransitGatewayConnectPeer(), connetPeerResourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccCheckTransitGatewayConnectPeerAssociationDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_networkmanager_customer_gateway_association" { + continue + } + + globalNetworkID, connectPeerARN, err := tfnetworkmanager.TransitGatewayConnectPeerAssociationParseResourceID(rs.Primary.ID) + + if err != nil { + return err + } + + _, err = tfnetworkmanager.FindTransitGatewayConnectPeerAssociationByTwoPartKey(context.TODO(), conn, globalNetworkID, connectPeerARN) + + if tfresource.NotFound(err) { + continue + } + + if err != nil { + return err + } + + return fmt.Errorf("Network Manager Transit Gateway Connect Peer Association %s still exists", rs.Primary.ID) + } + + return nil +} + +func testAccCheckTransitGatewayConnectPeerAssociationExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No Network Manager Transit Gateway Connect Peer Association ID is set") + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn + + globalNetworkID, connectPeerARN, err := tfnetworkmanager.TransitGatewayConnectPeerAssociationParseResourceID(rs.Primary.ID) + + if err != nil { + return err + } + + _, err = tfnetworkmanager.FindTransitGatewayConnectPeerAssociationByTwoPartKey(context.TODO(), conn, globalNetworkID, connectPeerARN) + + if err != nil { + return err + } + + return nil + } +} + +func testAccTransitGatewayConnectPeerAssociationConfig(rName string) string { + return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptInDefaultExclude(), fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" + + tags = { + Name = %[1]q + } +} + +resource "aws_subnet" "test" { + availability_zone = data.aws_availability_zones.available.names[0] + cidr_block = "10.0.0.0/24" + vpc_id = aws_vpc.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_ec2_transit_gateway" "test" { + transit_gateway_cidr_blocks = ["10.20.30.0/24"] + + tags = { + Name = %[1]q + } +} + +resource "aws_ec2_transit_gateway_vpc_attachment" "test" { + subnet_ids = [aws_subnet.test.id] + transit_gateway_id = aws_ec2_transit_gateway.test.id + vpc_id = aws_vpc.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_ec2_transit_gateway_connect" "test" { + transit_gateway_id = aws_ec2_transit_gateway.test.id + transport_attachment_id = aws_ec2_transit_gateway_vpc_attachment.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_ec2_transit_gateway_connect_peer" "test" { + inside_cidr_blocks = ["169.254.200.0/29"] + peer_address = "1.1.1.1" + transit_gateway_attachment_id = aws_ec2_transit_gateway_connect.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_global_network" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_device" "test" { + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_transit_gateway_registration" "test" { + global_network_id = aws_networkmanager_global_network.test.id + transit_gateway_arn = aws_ec2_transit_gateway.test.arn + + depends_on = [aws_ec2_transit_gateway_connect_peer.test] +} + +resource "aws_networkmanager_transit_gateway_connect_peer_association" "test" { + global_network_id = aws_networkmanager_global_network.test.id + device_id = aws_networkmanager_device.test.id + + transit_gateway_connect_peer_arn = aws_ec2_transit_gateway_connect_peer.test.arn + + depends_on = [aws_networkmanager_transit_gateway_registration.test] +} +`, rName)) +} diff --git a/website/docs/r/networkmanager_transit_gateway_connect_peer_association.html.markdown b/website/docs/r/networkmanager_transit_gateway_connect_peer_association.html.markdown new file mode 100644 index 00000000000..403439f73ba --- /dev/null +++ b/website/docs/r/networkmanager_transit_gateway_connect_peer_association.html.markdown @@ -0,0 +1,43 @@ +--- +subcategory: "Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_transit_gateway_connect_peer_association" +description: |- + Associates a transit gateway Connect peer with a device, and optionally, with a link. +--- + +# Resource: aws_networkmanager_transit_gateway_connect_peer_association + +Associates a transit gateway Connect peer with a device, and optionally, with a link. +If you specify a link, it must be associated with the specified device. + +## Example Usage + +```terraform +resource "aws_networkmanager_transit_gateway_connect_peer_association" "example" { + global_network_id = aws_networkmanager_global_network.example.id + device_id = aws_networkmanager_device.example.id + transit_gateway_connect_peer_arn = aws_ec2_transit_gateway_connect_peer.example.arn +} +``` + +## Argument Reference + +The following arguments are supported: + +* `device_id` - (Required) The ID of the device. +* `global_network_id` - (Required) The ID of the global network. +* `link_id` - (Optional) The ID of the link. +* `transit_gateway_connect_peer_arn` - (Required) The Amazon Resource Name (ARN) of the Connect peer. + +## Attributes Reference + +No additional attributes are exported. + +## Import + +`aws_networkmanager_transit_gateway_connect_peer_association` can be imported using the global network ID and customer gateway ARN, e.g. + +``` +$ terraform import aws_networkmanager_transit_gateway_connect_peer_association.example global-network-0d47f6t230mz46dy4,arn:aws:ec2:us-west-2:123456789012:transit-gateway-connect-peer/tgw-connect-peer-12345678 +``` From df93ce94c57c16e294dbde758824d6b45dbfd6a4 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 11 Mar 2022 15:52:01 -0500 Subject: [PATCH 140/229] Fix terrafmt error. --- .../transit_gateway_connect_peer_association_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/networkmanager/transit_gateway_connect_peer_association_test.go b/internal/service/networkmanager/transit_gateway_connect_peer_association_test.go index 26e055cb27c..7c49c03e71e 100644 --- a/internal/service/networkmanager/transit_gateway_connect_peer_association_test.go +++ b/internal/service/networkmanager/transit_gateway_connect_peer_association_test.go @@ -248,8 +248,8 @@ resource "aws_networkmanager_transit_gateway_registration" "test" { } resource "aws_networkmanager_transit_gateway_connect_peer_association" "test" { - global_network_id = aws_networkmanager_global_network.test.id - device_id = aws_networkmanager_device.test.id + global_network_id = aws_networkmanager_global_network.test.id + device_id = aws_networkmanager_device.test.id transit_gateway_connect_peer_arn = aws_ec2_transit_gateway_connect_peer.test.arn From e4e40e6aa119ee32da57974b4f33b8e1247daf83 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sat, 12 Mar 2022 15:15:43 -0500 Subject: [PATCH 141/229] r/aws_networkmanager_connection: New resource. Acceptance test output: % make testacc TESTS=TestAccNetworkManagerConnection_serial PKG=networkmanager ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/networkmanager/... -v -count 1 -parallel 20 -run='TestAccNetworkManagerConnection_serial' -timeout 180m === RUN TestAccNetworkManagerConnection_serial === RUN TestAccNetworkManagerConnection_serial/descriptionAndLinks === RUN TestAccNetworkManagerConnection_serial/basic === RUN TestAccNetworkManagerConnection_serial/disappears === RUN TestAccNetworkManagerConnection_serial/tags --- PASS: TestAccNetworkManagerConnection_serial (158.75s) --- PASS: TestAccNetworkManagerConnection_serial/descriptionAndLinks (48.48s) --- PASS: TestAccNetworkManagerConnection_serial/basic (28.73s) --- PASS: TestAccNetworkManagerConnection_serial/disappears (26.78s) --- PASS: TestAccNetworkManagerConnection_serial/tags (54.75s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 162.480s --- .changelog/13251.txt | 4 + internal/provider/provider.go | 1 + internal/service/networkmanager/connection.go | 385 +++++++++++++++++ .../service/networkmanager/connection_test.go | 408 ++++++++++++++++++ .../r/networkmanager_connection.html.markdown | 49 +++ 5 files changed, 847 insertions(+) create mode 100644 internal/service/networkmanager/connection.go create mode 100644 internal/service/networkmanager/connection_test.go create mode 100644 website/docs/r/networkmanager_connection.html.markdown diff --git a/.changelog/13251.txt b/.changelog/13251.txt index e806d5f73f3..dc73df6022a 100644 --- a/.changelog/13251.txt +++ b/.changelog/13251.txt @@ -30,6 +30,10 @@ aws_networkmanager_customer_gateway_association aws_networkmanager_transit_gateway_connect_peer_association ``` +```release-note:new-resource +aws_networkmanager_connection +``` + ```release-note:new-data-source aws_networkmanager_global_network ``` diff --git a/internal/provider/provider.go b/internal/provider/provider.go index a13352293c1..685c5270484 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1586,6 +1586,7 @@ func Provider() *schema.Provider { "aws_networkfirewall_resource_policy": networkfirewall.ResourceResourcePolicy(), "aws_networkfirewall_rule_group": networkfirewall.ResourceRuleGroup(), + "aws_networkmanager_connection": networkmanager.ResourceConnection(), "aws_networkmanager_customer_gateway_association": networkmanager.ResourceCustomerGatewayAssociation(), "aws_networkmanager_device": networkmanager.ResourceDevice(), "aws_networkmanager_global_network": networkmanager.ResourceGlobalNetwork(), diff --git a/internal/service/networkmanager/connection.go b/internal/service/networkmanager/connection.go new file mode 100644 index 00000000000..bf8f1853a10 --- /dev/null +++ b/internal/service/networkmanager/connection.go @@ -0,0 +1,385 @@ +package networkmanager + +import ( + "context" + "fmt" + "log" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/arn" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/internal/verify" +) + +func ResourceConnection() *schema.Resource { + return &schema.Resource{ + CreateWithoutTimeout: resourceConnectionCreate, + ReadWithoutTimeout: resourceConnectionRead, + UpdateWithoutTimeout: resourceConnectionUpdate, + DeleteWithoutTimeout: resourceConnectionDelete, + + Importer: &schema.ResourceImporter{ + StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + parsedARN, err := arn.Parse(d.Id()) + + if err != nil { + return nil, fmt.Errorf("error parsing ARN (%s): %w", d.Id(), err) + } + + // See https://docs.aws.amazon.com/service-authorization/latest/reference/list_networkmanager.html#networkmanager-resources-for-iam-policies. + resourceParts := strings.Split(parsedARN.Resource, "/") + + if actual, expected := len(resourceParts), 3; actual < expected { + return nil, fmt.Errorf("expected at least %d resource parts in ARN (%s), got: %d", expected, d.Id(), actual) + } + + d.SetId(resourceParts[2]) + d.Set("global_network_id", resourceParts[1]) + + return []*schema.ResourceData{d}, nil + }, + }, + + CustomizeDiff: verify.SetTagsDiff, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Update: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "connected_device_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "connected_link_id": { + Type: schema.TypeString, + Optional: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 256), + }, + "device_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "global_network_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "link_id": { + Type: schema.TypeString, + Optional: true, + }, + "tags": tftags.TagsSchema(), + "tags_all": tftags.TagsSchemaComputed(), + }, + } +} + +func resourceConnectionCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{}))) + + globalNetworkID := d.Get("global_network_id").(string) + + input := &networkmanager.CreateConnectionInput{ + ConnectedDeviceId: aws.String(d.Get("connected_device_id").(string)), + DeviceId: aws.String(d.Get("device_id").(string)), + GlobalNetworkId: aws.String(globalNetworkID), + } + + if v, ok := d.GetOk("connected_link_id"); ok { + input.ConnectedLinkId = aws.String(v.(string)) + } + + if v, ok := d.GetOk("description"); ok { + input.Description = aws.String(v.(string)) + } + + if v, ok := d.GetOk("link_id"); ok { + input.LinkId = aws.String(v.(string)) + } + + if len(tags) > 0 { + input.Tags = Tags(tags.IgnoreAWS()) + } + + log.Printf("[DEBUG] Creating Network Manager Connection: %s", input) + output, err := conn.CreateConnectionWithContext(ctx, input) + + if err != nil { + return diag.Errorf("error creating Network Manager Connection: %s", err) + } + + d.SetId(aws.StringValue(output.Connection.ConnectionId)) + + if _, err := waitConnectionCreated(ctx, conn, globalNetworkID, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { + return diag.Errorf("error waiting for Network Manager Connection (%s) create: %s", d.Id(), err) + } + + return resourceConnectionRead(ctx, d, meta) +} + +func resourceConnectionRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig + + globalNetworkID := d.Get("global_network_id").(string) + connection, err := FindConnectionByTwoPartKey(ctx, conn, globalNetworkID, d.Id()) + + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Network Manager Connection %s not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return diag.Errorf("error reading Network Manager Connection (%s): %s", d.Id(), err) + } + + d.Set("arn", connection.ConnectionArn) + d.Set("connected_device_id", connection.ConnectedDeviceId) + d.Set("connected_link_id", connection.ConnectedLinkId) + d.Set("description", connection.Description) + d.Set("device_id", connection.DeviceId) + d.Set("global_network_id", connection.GlobalNetworkId) + d.Set("link_id", connection.LinkId) + + tags := KeyValueTags(connection.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return diag.Errorf("error setting tags: %s", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return diag.Errorf("error setting tags_all: %s", err) + } + + return nil +} + +func resourceConnectionUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + if d.HasChangesExcept("tags", "tags_all") { + globalNetworkID := d.Get("global_network_id").(string) + input := &networkmanager.UpdateConnectionInput{ + ConnectedLinkId: aws.String(d.Get("connected_link_id").(string)), + ConnectionId: aws.String(d.Id()), + Description: aws.String(d.Get("description").(string)), + GlobalNetworkId: aws.String(globalNetworkID), + LinkId: aws.String(d.Get("link_id").(string)), + } + + log.Printf("[DEBUG] Updating Network Manager Connection: %s", input) + _, err := conn.UpdateConnectionWithContext(ctx, input) + + if err != nil { + return diag.Errorf("error updating Network Manager Connection (%s): %s", d.Id(), err) + } + + if _, err := waitConnectionUpdated(ctx, conn, globalNetworkID, d.Id(), d.Timeout(schema.TimeoutUpdate)); err != nil { + return diag.Errorf("error waiting for Network Manager Connection (%s) update: %s", d.Id(), err) + } + } + + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") + + if err := UpdateTags(conn, d.Get("arn").(string), o, n); err != nil { + return diag.Errorf("error updating Network Manager Connection (%s) tags: %s", d.Id(), err) + } + } + + return resourceConnectionRead(ctx, d, meta) +} + +func resourceConnectionDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + + globalNetworkID := d.Get("global_network_id").(string) + + log.Printf("[DEBUG] Deleting Network Manager Connection: %s", d.Id()) + _, err := conn.DeleteConnectionWithContext(ctx, &networkmanager.DeleteConnectionInput{ + ConnectionId: aws.String(d.Id()), + GlobalNetworkId: aws.String(globalNetworkID), + }) + + if globalNetworkIDNotFoundError(err) || tfawserr.ErrCodeEquals(err, networkmanager.ErrCodeResourceNotFoundException) { + return nil + } + + if err != nil { + return diag.Errorf("error deleting Network Manager Connection (%s): %s", d.Id(), err) + } + + if _, err := waitConnectionDeleted(ctx, conn, globalNetworkID, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil { + return diag.Errorf("error waiting for Network Manager Connection (%s) delete: %s", d.Id(), err) + } + + return nil +} + +func FindConnection(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.GetConnectionsInput) (*networkmanager.Connection, error) { + output, err := FindConnections(ctx, conn, input) + + if err != nil { + return nil, err + } + + if len(output) == 0 || output[0] == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } + + return output[0], nil +} + +func FindConnections(ctx context.Context, conn *networkmanager.NetworkManager, input *networkmanager.GetConnectionsInput) ([]*networkmanager.Connection, error) { + var output []*networkmanager.Connection + + err := conn.GetConnectionsPagesWithContext(ctx, input, func(page *networkmanager.GetConnectionsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.Connections { + if v == nil { + continue + } + + output = append(output, v) + } + + return !lastPage + }) + + if globalNetworkIDNotFoundError(err) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + return output, nil +} + +func FindConnectionByTwoPartKey(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, connectionID string) (*networkmanager.Connection, error) { + input := &networkmanager.GetConnectionsInput{ + ConnectionIds: aws.StringSlice([]string{connectionID}), + GlobalNetworkId: aws.String(globalNetworkID), + } + + output, err := FindConnection(ctx, conn, input) + + if err != nil { + return nil, err + } + + // Eventual consistency check. + if aws.StringValue(output.GlobalNetworkId) != globalNetworkID || aws.StringValue(output.ConnectionId) != connectionID { + return nil, &resource.NotFoundError{ + LastRequest: input, + } + } + + return output, nil +} + +func statusConnectionState(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, connectionID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + output, err := FindConnectionByTwoPartKey(ctx, conn, globalNetworkID, connectionID) + + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return output, aws.StringValue(output.State), nil + } +} + +func waitConnectionCreated(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, connectionID string, timeout time.Duration) (*networkmanager.Connection, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.ConnectionStatePending}, + Target: []string{networkmanager.ConnectionStateAvailable}, + Timeout: timeout, + Refresh: statusConnectionState(ctx, conn, globalNetworkID, connectionID), + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*networkmanager.Connection); ok { + return output, err + } + + return nil, err +} + +func waitConnectionDeleted(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, connectionID string, timeout time.Duration) (*networkmanager.Connection, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.ConnectionStateDeleting}, + Target: []string{}, + Timeout: timeout, + Refresh: statusConnectionState(ctx, conn, globalNetworkID, connectionID), + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*networkmanager.Connection); ok { + return output, err + } + + return nil, err +} + +func waitConnectionUpdated(ctx context.Context, conn *networkmanager.NetworkManager, globalNetworkID, connectionID string, timeout time.Duration) (*networkmanager.Connection, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{networkmanager.ConnectionStateUpdating}, + Target: []string{networkmanager.ConnectionStateAvailable}, + Timeout: timeout, + Refresh: statusConnectionState(ctx, conn, globalNetworkID, connectionID), + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*networkmanager.Connection); ok { + return output, err + } + + return nil, err +} diff --git a/internal/service/networkmanager/connection_test.go b/internal/service/networkmanager/connection_test.go new file mode 100644 index 00000000000..8ad62fd6726 --- /dev/null +++ b/internal/service/networkmanager/connection_test.go @@ -0,0 +1,408 @@ +package networkmanager_test + +import ( + "context" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/networkmanager" + 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" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tfnetworkmanager "github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" +) + +func TestAccNetworkManagerConnection_serial(t *testing.T) { + testCases := map[string]func(t *testing.T){ + "basic": testAccNetworkManagerConnection_basic, + "disappears": testAccNetworkManagerConnection_disappears, + "tags": testAccNetworkManagerConnection_tags, + "descriptionAndLinks": testAccNetworkManagerConnection_descriptionAndLinks, + } + + for name, tc := range testCases { + tc := tc + t.Run(name, func(t *testing.T) { + tc(t) + }) + } +} + +func testAccNetworkManagerConnection_basic(t *testing.T) { + resourceName := "aws_networkmanager_connection.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckConnectionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccConnectionConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckConnectionExists(resourceName), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "connected_link_id", ""), + resource.TestCheckResourceAttr(resourceName, "description", ""), + resource.TestCheckResourceAttr(resourceName, "link_id", ""), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccConnectionImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, + }, + }) +} + +func testAccNetworkManagerConnection_disappears(t *testing.T) { + resourceName := "aws_networkmanager_connection.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckConnectionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccConnectionConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckConnectionExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfnetworkmanager.ResourceConnection(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccNetworkManagerConnection_tags(t *testing.T) { + resourceName := "aws_networkmanager_connection.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckConnectionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccConnectionConfigTags1(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckConnectionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccConnectionImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, + { + Config: testAccConnectionConfigTags2(rName, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckConnectionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccConnectionConfigTags1(rName, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckConnectionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + }, + }) +} + +func testAccNetworkManagerConnection_descriptionAndLinks(t *testing.T) { + resourceName := "aws_networkmanager_connection.test" + link1ResourceName := "aws_networkmanager_link.test1" + link2ResourceName := "aws_networkmanager_link.test2" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckConnectionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccConnectionDescriptionAndLinksConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckConnectionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "connected_link_id", ""), + resource.TestCheckResourceAttr(resourceName, "description", "description1"), + resource.TestCheckResourceAttrPair(resourceName, "link_id", link1ResourceName, "id"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccConnectionImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, + { + Config: testAccConnectionDescriptionAndLinksUpdatedConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckConnectionExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "connected_link_id", link2ResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "description", "description2"), + resource.TestCheckResourceAttrPair(resourceName, "link_id", link1ResourceName, "id"), + ), + }, + }, + }) +} + +func testAccCheckConnectionDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_networkmanager_device" { + continue + } + + _, err := tfnetworkmanager.FindConnectionByTwoPartKey(context.TODO(), conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) + + if tfresource.NotFound(err) { + continue + } + + if err != nil { + return err + } + + return fmt.Errorf("Network Manager Connection %s still exists", rs.Primary.ID) + } + + return nil +} + +func testAccCheckConnectionExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No Network Manager Connection ID is set") + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).NetworkManagerConn + + _, err := tfnetworkmanager.FindConnectionByTwoPartKey(context.TODO(), conn, rs.Primary.Attributes["global_network_id"], rs.Primary.ID) + + if err != nil { + return err + } + + return nil + } +} + +func testAccConnectionBaseConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = %[1]q + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + description = %[1]q + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_device" "test1" { + global_network_id = aws_networkmanager_global_network.test.id + + description = "%[1]s-1" + + site_id = aws_networkmanager_site.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_device" "test2" { + global_network_id = aws_networkmanager_global_network.test.id + + description = "%[1]s-2" + + site_id = aws_networkmanager_site.test.id + + tags = { + Name = %[1]q + } + + # Create one device at a time. + depends_on = [aws_networkmanager_device.test1] +} +`, rName) +} + +func testAccConnectionConfig(rName string) string { + return acctest.ConfigCompose(testAccConnectionBaseConfig(rName), ` +resource "aws_networkmanager_connection" "test" { + global_network_id = aws_networkmanager_global_network.test.id + device_id = aws_networkmanager_device.test1.id + connected_device_id = aws_networkmanager_device.test2.id +} +`) +} + +func testAccConnectionConfigTags1(rName, tagKey1, tagValue1 string) string { + return acctest.ConfigCompose(testAccConnectionBaseConfig(rName), fmt.Sprintf(` +resource "aws_networkmanager_connection" "test" { + global_network_id = aws_networkmanager_global_network.test.id + device_id = aws_networkmanager_device.test1.id + connected_device_id = aws_networkmanager_device.test2.id + + tags = { + %[2]q = %[3]q + } +} +`, rName, tagKey1, tagValue1)) +} + +func testAccConnectionConfigTags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return acctest.ConfigCompose(testAccConnectionBaseConfig(rName), fmt.Sprintf(` +resource "aws_networkmanager_connection" "test" { + global_network_id = aws_networkmanager_global_network.test.id + device_id = aws_networkmanager_device.test1.id + connected_device_id = aws_networkmanager_device.test2.id + + tags = { + %[2]q = %[3]q + %[4]q = %[5]q + } +} +`, rName, tagKey1, tagValue1, tagKey2, tagValue2)) +} + +func testAccConnectionDescriptionAndLinksBaseConfig(rName string) string { + return acctest.ConfigCompose(testAccConnectionBaseConfig(rName), fmt.Sprintf(` +resource "aws_networkmanager_link" "test1" { + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id + + description = "%[1]s-1" + + bandwidth { + download_speed = 50 + upload_speed = 10 + } + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_link" "test2" { + global_network_id = aws_networkmanager_global_network.test.id + site_id = aws_networkmanager_site.test.id + + description = "%[1]s-2" + + bandwidth { + download_speed = 100 + upload_speed = 20 + } + + tags = { + Name = %[1]q + } + + # Create one link at a time. + depends_on = [aws_networkmanager_link.test1] +} + +resource "aws_networkmanager_link_association" "test1" { + global_network_id = aws_networkmanager_global_network.test.id + link_id = aws_networkmanager_link.test1.id + device_id = aws_networkmanager_device.test1.id +} + +resource "aws_networkmanager_link_association" "test2" { + global_network_id = aws_networkmanager_global_network.test.id + link_id = aws_networkmanager_link.test2.id + device_id = aws_networkmanager_device.test2.id +} +`, rName)) +} + +func testAccConnectionDescriptionAndLinksConfig(rName string) string { + return acctest.ConfigCompose(testAccConnectionDescriptionAndLinksBaseConfig(rName), fmt.Sprintf(` +resource "aws_networkmanager_connection" "test" { + global_network_id = aws_networkmanager_global_network.test.id + device_id = aws_networkmanager_device.test1.id + connected_device_id = aws_networkmanager_device.test2.id + + description = "description1" + + link_id = aws_networkmanager_link.test1.id + + tags = { + Name = %[1]q + } + + depends_on = [aws_networkmanager_link_association.test1, aws_networkmanager_link_association.test2] +} +`, rName)) +} + +func testAccConnectionDescriptionAndLinksUpdatedConfig(rName string) string { + return acctest.ConfigCompose(testAccConnectionDescriptionAndLinksBaseConfig(rName), fmt.Sprintf(` +resource "aws_networkmanager_connection" "test" { + global_network_id = aws_networkmanager_global_network.test.id + device_id = aws_networkmanager_device.test1.id + connected_device_id = aws_networkmanager_device.test2.id + + description = "description2" + + link_id = aws_networkmanager_link.test1.id + connected_link_id = aws_networkmanager_link.test2.id + + tags = { + Name = %[1]q + } + + depends_on = [aws_networkmanager_link_association.test1, aws_networkmanager_link_association.test2] +} +`, rName)) +} + +func testAccConnectionImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("Not found: %s", resourceName) + } + + return rs.Primary.Attributes["arn"], nil + } +} diff --git a/website/docs/r/networkmanager_connection.html.markdown b/website/docs/r/networkmanager_connection.html.markdown new file mode 100644 index 00000000000..d46ab005151 --- /dev/null +++ b/website/docs/r/networkmanager_connection.html.markdown @@ -0,0 +1,49 @@ +--- +subcategory: "Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_connection" +description: |- + Creates a connection between two devices. +--- + +# Resource: aws_networkmanager_connection + +Creates a connection between two devices. +The devices can be a physical or virtual appliance that connects to a third-party appliance in a VPC, or a physical appliance that connects to another physical appliance in an on-premises network. + +## Example Usage + +```terraform +resource "aws_networkmanager_connection" "example" { + global_network_id = aws_networkmanager_global_network.example.id + device_id = aws_networkmanager_device.example1.id + connected_device_id = aws_networkmanager_device.example2.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `connected_device_id` - (Required) The ID of the second device in the connection. +* `connected_link_id` - (Optional) The ID of the link for the second device. +* `description` - (Optional) A description of the connection. +* `device_id` - (Required) The ID of the first device in the connection. +* `global_network_id` - (Required) The ID of the global network. +* `link_id` - (Optional) The ID of the link for the first device. +* `tags` - (Optional) Key-value tags for the connection. If configured with a provider [`default_tags` configuration block](https://www.terraform.io/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - The Amazon Resource Name (ARN) of the connection. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](https://www.terraform.io/docs/providers/aws/index.html#default_tags-configuration-block). + +## Import + +`aws_networkmanager_connection` can be imported using the connection ARN, e.g. + +``` +$ terraform import aws_networkmanager_connection.example arn:aws:networkmanager::123456789012:device/global-network-0d47f6t230mz46dy4/connection-07f6fd08867abc123 +``` From 7c183b149da928a6872a7ad0ec75e767e10f6f77 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sat, 12 Mar 2022 15:38:43 -0500 Subject: [PATCH 142/229] Sweep connections. --- internal/service/networkmanager/sweep.go | 75 ++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/internal/service/networkmanager/sweep.go b/internal/service/networkmanager/sweep.go index f5da811169b..791e662f8e9 100644 --- a/internal/service/networkmanager/sweep.go +++ b/internal/service/networkmanager/sweep.go @@ -52,6 +52,14 @@ func init() { resource.AddTestSweepers("aws_networkmanager_link_association", &resource.Sweeper{ Name: "aws_networkmanager_link_association", F: sweepLinkAssociations, + Dependencies: []string{ + "aws_networkmanager_connection", + }, + }) + + resource.AddTestSweepers("aws_networkmanager_connection", &resource.Sweeper{ + Name: "aws_networkmanager_connection", + F: sweepConnections, }) } @@ -364,3 +372,70 @@ func sweepLinkAssociations(region string) error { return sweeperErrs.ErrorOrNil() } + +func sweepConnections(region string) error { + client, err := sweep.SharedRegionalSweepClient(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*conns.AWSClient).NetworkManagerConn + input := &networkmanager.DescribeGlobalNetworksInput{} + var sweeperErrs *multierror.Error + sweepResources := make([]*sweep.SweepResource, 0) + + err = conn.DescribeGlobalNetworksPages(input, func(page *networkmanager.DescribeGlobalNetworksOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.GlobalNetworks { + input := &networkmanager.GetConnectionsInput{ + GlobalNetworkId: v.GlobalNetworkId, + } + + err := conn.GetConnectionsPages(input, func(page *networkmanager.GetConnectionsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.Connections { + r := ResourceConnection() + d := r.Data(nil) + d.SetId(aws.StringValue(v.ConnectionId)) + d.Set("global_network_id", v.GlobalNetworkId) + + sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) + } + + return !lastPage + }) + + if sweep.SkipSweepError(err) { + continue + } + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing Network Manager Connections (%s): %w", region, err)) + } + } + + return !lastPage + }) + + if sweep.SkipSweepError(err) { + log.Printf("[WARN] Skipping Network Manager Connection sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing Network Manager Global Networks (%s): %w", region, err)) + } + + err = sweep.SweepOrchestrator(sweepResources) + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error sweeping Network Manager Connections (%s): %w", region, err)) + } + + return sweeperErrs.ErrorOrNil() +} From a4622c585a0a6dcc485623e8c1b43c92f1855427 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sat, 12 Mar 2022 15:44:46 -0500 Subject: [PATCH 143/229] Documentation corrections. --- website/docs/d/networkmanager_link.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/d/networkmanager_link.html.markdown b/website/docs/d/networkmanager_link.html.markdown index de43bec99a9..bf9800def42 100644 --- a/website/docs/d/networkmanager_link.html.markdown +++ b/website/docs/d/networkmanager_link.html.markdown @@ -6,9 +6,9 @@ description: |- Retrieve information about a link. --- -# Data Source: aws_networkmanager_site +# Data Source: aws_networkmanager_link -Retrieve information about a site. +Retrieve information about a link. ## Example Usage From 5cc0af9b448d1f166ea5e54bb56d61ea96733aae Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sat, 12 Mar 2022 16:02:24 -0500 Subject: [PATCH 144/229] d/aws_networkmanager_connection: New data source. Acceptance test output: % make testacc TESTS=TestAccNetworkManagerConnectionDataSource_ PKG=networkmanager ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/networkmanager/... -v -count 1 -parallel 20 -run='TestAccNetworkManagerConnectionDataSource_' -timeout 180m === RUN TestAccNetworkManagerConnectionDataSource_basic === PAUSE TestAccNetworkManagerConnectionDataSource_basic === CONT TestAccNetworkManagerConnectionDataSource_basic --- PASS: TestAccNetworkManagerConnectionDataSource_basic (31.87s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 35.389s --- .changelog/13251.txt | 4 + internal/provider/provider.go | 1 + .../networkmanager/connection_data_source.go | 81 +++++++++++++++++++ .../connection_data_source_test.go | 46 +++++++++++ website/docs/d/networkmanager_connection.html | 37 +++++++++ 5 files changed, 169 insertions(+) create mode 100644 internal/service/networkmanager/connection_data_source.go create mode 100644 internal/service/networkmanager/connection_data_source_test.go create mode 100644 website/docs/d/networkmanager_connection.html diff --git a/.changelog/13251.txt b/.changelog/13251.txt index dc73df6022a..af5c85abb28 100644 --- a/.changelog/13251.txt +++ b/.changelog/13251.txt @@ -73,3 +73,7 @@ resource/aws_ec2_transit_gateway_connect_peer: Add `arn` attribute ```release-note:enhancement data-source/aws_ec2_transit_gateway_connect_peer: Add `arn` attribute ``` + +```release-note:new-data-source +aws_networkmanager_connection +``` diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 685c5270484..bd769e0b546 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -713,6 +713,7 @@ func Provider() *schema.Provider { "aws_neptune_engine_version": neptune.DataSourceEngineVersion(), "aws_neptune_orderable_db_instance": neptune.DataSourceOrderableDBInstance(), + "aws_networkmanager_connection": networkmanager.DataSourceConnection(), "aws_networkmanager_device": networkmanager.DataSourceDevice(), "aws_networkmanager_devices": networkmanager.DataSourceDevices(), "aws_networkmanager_global_network": networkmanager.DataSourceGlobalNetwork(), diff --git a/internal/service/networkmanager/connection_data_source.go b/internal/service/networkmanager/connection_data_source.go new file mode 100644 index 00000000000..743df865b65 --- /dev/null +++ b/internal/service/networkmanager/connection_data_source.go @@ -0,0 +1,81 @@ +package networkmanager + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" +) + +func DataSourceConnection() *schema.Resource { + return &schema.Resource{ + ReadWithoutTimeout: dataSourceConnectionRead, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "connected_device_id": { + Type: schema.TypeString, + Computed: true, + }, + "connected_link_id": { + Type: schema.TypeString, + Computed: true, + }, + "connection_id": { + Type: schema.TypeString, + Required: true, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "device_id": { + Type: schema.TypeString, + Computed: true, + }, + "global_network_id": { + Type: schema.TypeString, + Required: true, + }, + "link_id": { + Type: schema.TypeString, + Computed: true, + }, + "tags": tftags.TagsSchemaComputed(), + }, + } +} + +func dataSourceConnectionRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig + + globalNetworkID := d.Get("global_network_id").(string) + connectionID := d.Get("connection_id").(string) + connection, err := FindConnectionByTwoPartKey(ctx, conn, globalNetworkID, connectionID) + + if err != nil { + return diag.Errorf("error reading Network Manager Connection (%s): %s", connectionID, err) + } + + d.SetId(connectionID) + d.Set("arn", connection.ConnectionArn) + d.Set("connected_device_id", connection.ConnectedDeviceId) + d.Set("connected_link_id", connection.ConnectedLinkId) + d.Set("connection_id", connection.ConnectionId) + d.Set("description", connection.Description) + d.Set("device_id", connection.DeviceId) + d.Set("global_network_id", connection.GlobalNetworkId) + d.Set("link_id", connection.LinkId) + + if err := d.Set("tags", KeyValueTags(connection.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return diag.Errorf("error setting tags: %s", err) + } + + return nil +} diff --git a/internal/service/networkmanager/connection_data_source_test.go b/internal/service/networkmanager/connection_data_source_test.go new file mode 100644 index 00000000000..287f7111f5c --- /dev/null +++ b/internal/service/networkmanager/connection_data_source_test.go @@ -0,0 +1,46 @@ +package networkmanager_test + +import ( + "testing" + + "github.com/aws/aws-sdk-go/service/networkmanager" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" +) + +func TestAccNetworkManagerConnectionDataSource_basic(t *testing.T) { + dataSourceName := "data.aws_networkmanager_connection.test" + resourceName := "aws_networkmanager_connection.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccConnectionDataSourceConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(dataSourceName, "connected_device_id", resourceName, "connected_device_id"), + resource.TestCheckResourceAttrPair(dataSourceName, "connected_link_id", resourceName, "connected_link_id"), + resource.TestCheckResourceAttrPair(dataSourceName, "connection_id", resourceName, "id"), + resource.TestCheckResourceAttrPair(dataSourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttrPair(dataSourceName, "global_network_id", resourceName, "global_network_id"), + resource.TestCheckResourceAttrPair(dataSourceName, "link_id", resourceName, "link_id"), + resource.TestCheckResourceAttrPair(dataSourceName, "tags.%", resourceName, "tags.%"), + ), + }, + }, + }) +} + +func testAccConnectionDataSourceConfig(rName string) string { + return acctest.ConfigCompose(testAccConnectionDescriptionAndLinksConfig(rName), ` +data "aws_networkmanager_connection" "test" { + global_network_id = aws_networkmanager_global_network.test.id + connection_id = aws_networkmanager_connection.test.id +} +`) +} diff --git a/website/docs/d/networkmanager_connection.html b/website/docs/d/networkmanager_connection.html new file mode 100644 index 00000000000..151628d965d --- /dev/null +++ b/website/docs/d/networkmanager_connection.html @@ -0,0 +1,37 @@ +--- +subcategory: "Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_connection" +description: |- + Retrieve information about a connection. +--- + +# Data Source: aws_networkmanager_connection + +Retrieve information about a connection. + +## Example Usage + +```terraform +data "aws_networkmanager_connection" "example" { + global_network_id = var.global_network_id + connection_id = var.connection_id +} +``` + +## Argument Reference + +* `global_network_id` - (Required) The ID of the Global Network of the connection to retrieve. +* `connection_id` - (Required) The id of the specific connection to retrieve. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - The ARN of the connection. +* `connected_device_id` - The ID of the second device in the connection. +* `connected_link_id` - The ID of the link for the second device. +* `description` - A description of the connection. +* `device_id` - The ID of the first device in the connection. +* `link_id` - The ID of the link for the first device. +* `tags` - Key-value tags for the connection. From 8dcd9c0ded36be730d31bc599cd4d2caef04bbd9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sat, 12 Mar 2022 16:08:52 -0500 Subject: [PATCH 145/229] d/aws_networkmanager_link: Set 'link_id'. Acceptance test output: % make testacc TESTS=TestAccNetworkManagerLinkDataSource_ PKG=networkmanager ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/networkmanager/... -v -count 1 -parallel 20 -run='TestAccNetworkManagerLinkDataSource_' -timeout 180m === RUN TestAccNetworkManagerLinkDataSource_basic === PAUSE TestAccNetworkManagerLinkDataSource_basic === CONT TestAccNetworkManagerLinkDataSource_basic --- PASS: TestAccNetworkManagerLinkDataSource_basic (25.34s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 28.909s --- internal/service/networkmanager/link_data_source.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/service/networkmanager/link_data_source.go b/internal/service/networkmanager/link_data_source.go index 087cb471b16..06d254cfe06 100644 --- a/internal/service/networkmanager/link_data_source.go +++ b/internal/service/networkmanager/link_data_source.go @@ -86,6 +86,7 @@ func dataSourceLinkRead(ctx context.Context, d *schema.ResourceData, meta interf } d.Set("description", link.Description) d.Set("global_network_id", link.GlobalNetworkId) + d.Set("link_id", link.LinkId) d.Set("provider_name", link.Provider) d.Set("site_id", link.SiteId) d.Set("type", link.Type) From 173a2b9fd9cadc119522fa2b01f09d52f802da98 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sat, 12 Mar 2022 16:25:27 -0500 Subject: [PATCH 146/229] d/aws_networkmanager_connections: New data source. Acceptance test output: % make testacc TESTS=TestAccNetworkManagerConnectionsDataSource_ PKG=networkmanager ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/networkmanager/... -v -count 1 -parallel 20 -run='TestAccNetworkManagerConnectionsDataSource_' -timeout 180m === RUN TestAccNetworkManagerConnectionsDataSource_basic === PAUSE TestAccNetworkManagerConnectionsDataSource_basic === CONT TestAccNetworkManagerConnectionsDataSource_basic --- PASS: TestAccNetworkManagerConnectionsDataSource_basic (32.22s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/networkmanager 35.619s --- .changelog/13251.txt | 4 + internal/provider/provider.go | 1 + .../networkmanager/connections_data_source.go | 72 +++++++++ .../connections_data_source_test.go | 150 ++++++++++++++++++ .../networkmanager_connections.html.markdown | 35 ++++ 5 files changed, 262 insertions(+) create mode 100644 internal/service/networkmanager/connections_data_source.go create mode 100644 internal/service/networkmanager/connections_data_source_test.go create mode 100644 website/docs/d/networkmanager_connections.html.markdown diff --git a/.changelog/13251.txt b/.changelog/13251.txt index af5c85abb28..d76418807ed 100644 --- a/.changelog/13251.txt +++ b/.changelog/13251.txt @@ -77,3 +77,7 @@ data-source/aws_ec2_transit_gateway_connect_peer: Add `arn` attribute ```release-note:new-data-source aws_networkmanager_connection ``` + +```release-note:new-data-source +aws_networkmanager_connections +``` \ No newline at end of file diff --git a/internal/provider/provider.go b/internal/provider/provider.go index bd769e0b546..0a6e3584586 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -714,6 +714,7 @@ func Provider() *schema.Provider { "aws_neptune_orderable_db_instance": neptune.DataSourceOrderableDBInstance(), "aws_networkmanager_connection": networkmanager.DataSourceConnection(), + "aws_networkmanager_connections": networkmanager.DataSourceConnections(), "aws_networkmanager_device": networkmanager.DataSourceDevice(), "aws_networkmanager_devices": networkmanager.DataSourceDevices(), "aws_networkmanager_global_network": networkmanager.DataSourceGlobalNetwork(), diff --git a/internal/service/networkmanager/connections_data_source.go b/internal/service/networkmanager/connections_data_source.go new file mode 100644 index 00000000000..24c425d1221 --- /dev/null +++ b/internal/service/networkmanager/connections_data_source.go @@ -0,0 +1,72 @@ +package networkmanager + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/networkmanager" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" +) + +func DataSourceConnections() *schema.Resource { + return &schema.Resource{ + ReadWithoutTimeout: dataSourceConnectionsRead, + + Schema: map[string]*schema.Schema{ + "device_id": { + Type: schema.TypeString, + Optional: true, + }, + "global_network_id": { + Type: schema.TypeString, + Required: true, + }, + "ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "tags": tftags.TagsSchema(), + }, + } +} + +func dataSourceConnectionsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).NetworkManagerConn + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig + tagsToMatch := tftags.New(d.Get("tags").(map[string]interface{})).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) + + input := &networkmanager.GetConnectionsInput{ + GlobalNetworkId: aws.String(d.Get("global_network_id").(string)), + } + + if v, ok := d.GetOk("device_id"); ok { + input.DeviceId = aws.String(v.(string)) + } + + output, err := FindConnections(ctx, conn, input) + + if err != nil { + return diag.Errorf("error listing Network Manager Connections: %s", err) + } + + var connectionIDs []string + + for _, v := range output { + if len(tagsToMatch) > 0 { + if !KeyValueTags(v.Tags).ContainsAll(tagsToMatch) { + continue + } + } + + connectionIDs = append(connectionIDs, aws.StringValue(v.ConnectionId)) + } + + d.SetId(meta.(*conns.AWSClient).Region) + d.Set("ids", connectionIDs) + + return nil +} diff --git a/internal/service/networkmanager/connections_data_source_test.go b/internal/service/networkmanager/connections_data_source_test.go new file mode 100644 index 00000000000..dbd716664e9 --- /dev/null +++ b/internal/service/networkmanager/connections_data_source_test.go @@ -0,0 +1,150 @@ +package networkmanager_test + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/networkmanager" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" +) + +func TestAccNetworkManagerConnectionsDataSource_basic(t *testing.T) { + dataSourceAllName := "data.aws_networkmanager_connections.all" + dataSourceByTagsName := "data.aws_networkmanager_connections.by_tags" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, networkmanager.EndpointsID), + Providers: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccConnectionsDataSourceConfig(rName), + Check: resource.ComposeTestCheckFunc( + acctest.CheckResourceAttrGreaterThanValue(dataSourceAllName, "ids.#", "1"), + resource.TestCheckResourceAttr(dataSourceByTagsName, "ids.#", "1"), + ), + }, + }, + }) +} + +func testAccConnectionsDataSourceConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_networkmanager_global_network" "test" { + description = %[1]q + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_site" "test" { + global_network_id = aws_networkmanager_global_network.test.id + + description = %[1]q + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_device" "test1" { + global_network_id = aws_networkmanager_global_network.test.id + + description = "%[1]s-1" + + site_id = aws_networkmanager_site.test.id + + tags = { + Name = %[1]q + } +} + +resource "aws_networkmanager_device" "test2" { + global_network_id = aws_networkmanager_global_network.test.id + + description = "%[1]s-2" + + site_id = aws_networkmanager_site.test.id + + tags = { + Name = %[1]q + } + + # Create one device at a time. + depends_on = [aws_networkmanager_device.test1] +} + +resource "aws_networkmanager_device" "test3" { + global_network_id = aws_networkmanager_global_network.test.id + + description = "%[1]s-3" + + site_id = aws_networkmanager_site.test.id + + tags = { + Name = %[1]q + } + + # Create one device at a time. + depends_on = [aws_networkmanager_device.test2] +} + +resource "aws_networkmanager_device" "test4" { + global_network_id = aws_networkmanager_global_network.test.id + + description = "%[1]s-4" + + site_id = aws_networkmanager_site.test.id + + tags = { + Name = %[1]q + } + + # Create one device at a time. + depends_on = [aws_networkmanager_device.test3] +} + +resource "aws_networkmanager_connection" "test1" { + global_network_id = aws_networkmanager_global_network.test.id + device_id = aws_networkmanager_device.test1.id + connected_device_id = aws_networkmanager_device.test2.id + + description = "%[1]s-1" +} + +resource "aws_networkmanager_connection" "test2" { + global_network_id = aws_networkmanager_global_network.test.id + device_id = aws_networkmanager_device.test3.id + connected_device_id = aws_networkmanager_device.test4.id + + description = "%[1]s-2" + + tags = { + Name = %[1]q + } + + # Create one connection at a time. + depends_on = [aws_networkmanager_connection.test1] +} + +data "aws_networkmanager_connections" "all" { + global_network_id = aws_networkmanager_global_network.test.id + + depends_on = [aws_networkmanager_connection.test1, aws_networkmanager_connection.test2] +} + +data "aws_networkmanager_connections" "by_tags" { + global_network_id = aws_networkmanager_global_network.test.id + + tags = { + Name = %[1]q + } + + depends_on = [aws_networkmanager_connection.test1, aws_networkmanager_connection.test2] +} +`, rName) +} diff --git a/website/docs/d/networkmanager_connections.html.markdown b/website/docs/d/networkmanager_connections.html.markdown new file mode 100644 index 00000000000..1191aa3c781 --- /dev/null +++ b/website/docs/d/networkmanager_connections.html.markdown @@ -0,0 +1,35 @@ +--- +subcategory: "Network Manager" +layout: "aws" +page_title: "AWS: aws_networkmanager_connections" +description: |- + Retrieve information about connections. +--- + +# Data Source: aws_networkmanager_connections + +Retrieve information about connections. + +## Example Usage + +```terraform +data "aws_networkmanager_connections" "example" { + global_network_id = var.global_network_id + + tags = { + Env = "test" + } +} +``` + +## Argument Reference + +* `device_id` - (Optional) The ID of the device of the connections to retrieve. +* `global_network_id` - (Required) The ID of the Global Network of the connections to retrieve. +* `tags` - (Optional) Restricts the list to the connections with these tags. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `ids` - The IDs of the connections. From 441c71b4b0d606ef666d912a0bb41e8480c33146 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sat, 12 Mar 2022 16:26:31 -0500 Subject: [PATCH 147/229] Correct error message. --- internal/service/networkmanager/links_data_source.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/networkmanager/links_data_source.go b/internal/service/networkmanager/links_data_source.go index 303263f2394..c8c9502e1ad 100644 --- a/internal/service/networkmanager/links_data_source.go +++ b/internal/service/networkmanager/links_data_source.go @@ -66,7 +66,7 @@ func dataSourceLinksRead(ctx context.Context, d *schema.ResourceData, meta inter output, err := FindLinks(ctx, conn, input) if err != nil { - return diag.Errorf("error listing Network Manager Sites: %s", err) + return diag.Errorf("error listing Network Manager Links: %s", err) } var linkIDs []string From 429f662e412728ded6c57dd517b927cac71760c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Prieto=20Ballester?= Date: Sat, 12 Mar 2022 22:51:04 +0100 Subject: [PATCH 148/229] Lint fmt Terraform Test --- internal/service/transfer/server_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/transfer/server_test.go b/internal/service/transfer/server_test.go index 34dc4d229ab..78123078624 100644 --- a/internal/service/transfer/server_test.go +++ b/internal/service/transfer/server_test.go @@ -1225,8 +1225,8 @@ resource "aws_transfer_server" "test" {} func testAccServerDisplayBannersConfig() string { return ` resource "aws_transfer_server" "test" { - pre_display_banner = "This system is for the use of authorized users only" - post_display_banner = "This system is for the use of authorized users only" + pre_display_banner = "This system is for the use of authorized users only" + post_display_banner = "This system is for the use of authorized users only" } ` } From e9eea13dea3fdba944ecd05896cb6ca011e0f78a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sat, 12 Mar 2022 17:07:10 -0500 Subject: [PATCH 149/229] Rename documentation file. --- ...er_connection.html => networkmanager_connection.html.markdown} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename website/docs/d/{networkmanager_connection.html => networkmanager_connection.html.markdown} (100%) diff --git a/website/docs/d/networkmanager_connection.html b/website/docs/d/networkmanager_connection.html.markdown similarity index 100% rename from website/docs/d/networkmanager_connection.html rename to website/docs/d/networkmanager_connection.html.markdown From d445f144f07ee287d5a8d66dabae583204db3918 Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Sun, 6 Mar 2022 11:49:50 +0100 Subject: [PATCH 150/229] #23475 - Add `mysql` and `postgres` to validEngine func to support Multi-AZ DB clusters --- internal/service/rds/validate.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/service/rds/validate.go b/internal/service/rds/validate.go index e22f7b44cbc..6e3da6ad67e 100644 --- a/internal/service/rds/validate.go +++ b/internal/service/rds/validate.go @@ -148,6 +148,8 @@ func validEngine() schema.SchemaValidateFunc { "aurora", "aurora-mysql", "aurora-postgresql", + "postgres", + "mysql", }, false) } From 3b3aeccd7da6cd14f0647659d9a08727a78b0c58 Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Sun, 6 Mar 2022 14:26:54 +0100 Subject: [PATCH 151/229] #23475 - Add required parameters: storage_type, allocated_storage, iops and db_cluster_instance_class --- internal/service/rds/cluster.go | 62 +++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/internal/service/rds/cluster.go b/internal/service/rds/cluster.go index 681a403b00b..089ca593ce1 100644 --- a/internal/service/rds/cluster.go +++ b/internal/service/rds/cluster.go @@ -157,6 +157,11 @@ func ResourceCluster() *schema.Resource { Computed: true, }, + "db_cluster_instance_class": { + Type: schema.TypeString, + Optional: true, + }, + "engine": { Type: schema.TypeString, Optional: true, @@ -231,6 +236,22 @@ func ResourceCluster() *schema.Resource { }, }, + "allocated_storage": { + Type: schema.TypeInt, + Optional: true, + }, + + "storage_type": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "iops": { + Type: schema.TypeInt, + Optional: true, + }, + "storage_encrypted": { Type: schema.TypeBool, Optional: true, @@ -870,6 +891,10 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { createOpts.DBClusterParameterGroupName = aws.String(attr.(string)) } + if attr, ok := d.GetOk("db_cluster_instance_class"); ok { + createOpts.DBClusterInstanceClass = aws.String(attr.(string)) + } + if attr, ok := d.GetOk("engine_version"); ok { createOpts.EngineVersion = aws.String(attr.(string)) } @@ -922,6 +947,18 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { createOpts.ReplicationSourceIdentifier = aws.String(attr.(string)) } + if attr, ok := d.GetOkExists("allocated_storage"); ok { + createOpts.AllocatedStorage = aws.Int64(int64(attr.(int))) + } + + if attr, ok := d.GetOkExists("storage_type"); ok { + createOpts.StorageType = aws.String(attr.(string)) + } + + if attr, ok := d.GetOkExists("iops"); ok { + createOpts.Iops = aws.Int64(int64(attr.(int))) + } + if attr, ok := d.GetOkExists("storage_encrypted"); ok { createOpts.StorageEncrypted = aws.Bool(attr.(bool)) } @@ -1076,6 +1113,7 @@ func resourceClusterRead(d *schema.ResourceData, meta interface{}) error { } d.Set("endpoint", dbc.Endpoint) + d.Set("db_cluster_instance_class", dbc.DBClusterInstanceClass) d.Set("engine_mode", dbc.EngineMode) d.Set("engine", dbc.Engine) d.Set("hosted_zone_id", dbc.HostedZoneId) @@ -1103,7 +1141,11 @@ func resourceClusterRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("error setting scaling_configuration: %s", err) } + d.Set("allocated_storage", dbc.AllocatedStorage) + d.Set("storage_type", dbc.StorageType) + d.Set("iops", dbc.Iops) d.Set("storage_encrypted", dbc.StorageEncrypted) + d.Set("enable_http_endpoint", dbc.HttpEndpointEnabled) var vpcg []string @@ -1182,6 +1224,11 @@ func resourceClusterUpdate(d *schema.ResourceData, meta interface{}) error { requestUpdate = true } + if d.HasChange("db_cluster_instance_class") { + req.EngineVersion = aws.String(d.Get("db_cluster_instance_class").(string)) + requestUpdate = true + } + if d.HasChange("engine_version") { req.EngineVersion = aws.String(d.Get("engine_version").(string)) requestUpdate = true @@ -1201,6 +1248,21 @@ func resourceClusterUpdate(d *schema.ResourceData, meta interface{}) error { requestUpdate = true } + if d.HasChange("storage_type") { + req.StorageType = aws.String(d.Get("storage_type").(string)) + requestUpdate = true + } + + if d.HasChange("allocated_storage") { + req.AllocatedStorage = aws.Int64(int64(d.Get("allocated_storage").(int))) + requestUpdate = true + } + + if d.HasChange("iops") { + req.Iops = aws.Int64(int64(d.Get("iops").(int))) + requestUpdate = true + } + if d.HasChange("preferred_backup_window") { req.PreferredBackupWindow = aws.String(d.Get("preferred_backup_window").(string)) requestUpdate = true From 7523b4d0f96b47d4f5101c3c5aafbb60737fc0f4 Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Sun, 6 Mar 2022 18:51:50 +0100 Subject: [PATCH 152/229] Add acceptance tests for storage_type, allocated_storage, iops and db_cluster_instance_class attributes --- internal/service/rds/cluster_test.go | 176 +++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) diff --git a/internal/service/rds/cluster_test.go b/internal/service/rds/cluster_test.go index d0abe29c25e..d0f6e86082c 100644 --- a/internal/service/rds/cluster_test.go +++ b/internal/service/rds/cluster_test.go @@ -292,6 +292,94 @@ func TestAccRDSCluster_availabilityZones(t *testing.T) { }) } +func TestAccRDSCluster_storageType(t *testing.T) { + var dbCluster rds.DBCluster + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_rds_cluster.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccClusterConfig_StorageType(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckClusterExists(resourceName, &dbCluster), + resource.TestCheckResourceAttr(resourceName, "storage_type", "io1"), + ), + }, + }, + }) +} + +func TestAccRDSCluster_allocatedStorage(t *testing.T) { + var dbCluster rds.DBCluster + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_rds_cluster.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccClusterConfig_AllocatedStorage(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckClusterExists(resourceName, &dbCluster), + resource.TestCheckResourceAttr(resourceName, "allocated_storage", "100"), + ), + }, + }, + }) +} + +func TestAccRDSCluster_iops(t *testing.T) { + var dbCluster rds.DBCluster + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_rds_cluster.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccClusterConfig_Iops(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckClusterExists(resourceName, &dbCluster), + resource.TestCheckResourceAttr(resourceName, "iops", "300"), + ), + }, + }, + }) +} + +func TestAccRDSCluster_dbClusterInstanceClass(t *testing.T) { + var dbCluster rds.DBCluster + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_rds_cluster.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccClusterConfig_DbClusterInstanceClass(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckClusterExists(resourceName, &dbCluster), + resource.TestCheckResourceAttr(resourceName, "db_cluster_instance_class", "db.r6gd.xlarge"), + ), + }, + }, + }) +} + func TestAccRDSCluster_backtrackWindow(t *testing.T) { var dbCluster rds.DBCluster resourceName := "aws_rds_cluster.test" @@ -2127,6 +2215,94 @@ resource "aws_rds_cluster" "test" { `, rName) } +func testAccClusterConfig_StorageType(rName string) string { + return fmt.Sprintf(` +data "aws_availability_zones" "available" { + state = "available" +} + +resource "aws_rds_cluster" "test" { + apply_immediately = true + availability_zones = [data.aws_availability_zones.available.names[0], data.aws_availability_zones.available.names[1], data.aws_availability_zones.available.names[2]] + cluster_identifier = %q + db_cluster_instance_class = "db.r6gd.xlarge" + engine = "mysql" + storage_type = "io1" + allocated_storage = 100 + iops = 300 + master_password = "mustbeeightcharaters" + master_username = "test" + skip_final_snapshot = true +} +`, rName) +} + +func testAccClusterConfig_AllocatedStorage(rName string) string { + return fmt.Sprintf(` +data "aws_availability_zones" "available" { + state = "available" +} + +resource "aws_rds_cluster" "test" { + apply_immediately = true + availability_zones = [data.aws_availability_zones.available.names[0], data.aws_availability_zones.available.names[1], data.aws_availability_zones.available.names[2]] + cluster_identifier = %q + db_cluster_instance_class = "db.r6gd.xlarge" + engine = "mysql" + storage_type = "io1" + allocated_storage = 100 + iops = 300 + master_password = "mustbeeightcharaters" + master_username = "test" + skip_final_snapshot = true +} +`, rName) +} + +func testAccClusterConfig_Iops(rName string) string { + return fmt.Sprintf(` +data "aws_availability_zones" "available" { + state = "available" +} + +resource "aws_rds_cluster" "test" { + apply_immediately = true + availability_zones = [data.aws_availability_zones.available.names[0], data.aws_availability_zones.available.names[1], data.aws_availability_zones.available.names[2]] + cluster_identifier = %q + db_cluster_instance_class = "db.r6gd.xlarge" + engine = "mysql" + storage_type = "io1" + allocated_storage = 100 + iops = 300 + master_password = "mustbeeightcharaters" + master_username = "test" + skip_final_snapshot = true +} +`, rName) +} + +func testAccClusterConfig_DbClusterInstanceClass(rName string) string { + return fmt.Sprintf(` +data "aws_availability_zones" "available" { + state = "available" +} + +resource "aws_rds_cluster" "test" { + apply_immediately = true + availability_zones = [data.aws_availability_zones.available.names[0], data.aws_availability_zones.available.names[1], data.aws_availability_zones.available.names[2]] + cluster_identifier = %q + db_cluster_instance_class = "db.r6gd.xlarge" + engine = "mysql" + storage_type = "io1" + allocated_storage = 100 + iops = 300 + master_password = "mustbeeightcharaters" + master_username = "test" + skip_final_snapshot = true +} +`, rName) +} + func testAccClusterConfig_BacktrackWindow(backtrackWindow int) string { return fmt.Sprintf(` resource "aws_rds_cluster" "test" { From a3bbee52e7b1e44fdeaa2b52faf4ad73ca6721a1 Mon Sep 17 00:00:00 2001 From: Michael Ericksen Date: Sat, 12 Mar 2022 21:55:24 -0600 Subject: [PATCH 153/229] docs: use valid example id for import statement --- website/docs/r/api_gateway_vpc_link.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/api_gateway_vpc_link.html.markdown b/website/docs/r/api_gateway_vpc_link.html.markdown index 032f7ed9c9b..f797482c1b7 100644 --- a/website/docs/r/api_gateway_vpc_link.html.markdown +++ b/website/docs/r/api_gateway_vpc_link.html.markdown @@ -54,5 +54,5 @@ In addition to all arguments above, the following attributes are exported: API Gateway VPC Link can be imported using the `id`, e.g., ``` -$ terraform import aws_api_gateway_vpc_link.example +$ terraform import aws_api_gateway_vpc_link.example 12345abcde ``` From 4d55ce8f8dcfb6ee5fb8bd25b971da973c299610 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Mar 2022 06:05:36 +0000 Subject: [PATCH 154/229] build(deps): bump integrations/github in /infrastructure/repository Bumps [integrations/github](https://github.com/integrations/terraform-provider-github) from 4.20.0 to 4.21.0. - [Release notes](https://github.com/integrations/terraform-provider-github/releases) - [Changelog](https://github.com/integrations/terraform-provider-github/blob/main/CHANGELOG.md) - [Commits](https://github.com/integrations/terraform-provider-github/compare/v4.20.0...v4.21.0) --- updated-dependencies: - dependency-name: integrations/github dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- infrastructure/repository/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infrastructure/repository/main.tf b/infrastructure/repository/main.tf index 1833a12650c..2f9b000b5f7 100644 --- a/infrastructure/repository/main.tf +++ b/infrastructure/repository/main.tf @@ -10,7 +10,7 @@ terraform { required_providers { github = { source = "integrations/github" - version = "4.20.0" + version = "4.21.0" } } From 914d525db1a1582f7bc140d59d2e0b8efd7ca0d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Mar 2022 06:05:38 +0000 Subject: [PATCH 155/229] build(deps): bump tj-actions/changed-files from 17.2 to 18 Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 17.2 to 18. - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/v17.2...v18) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/terraform_provider.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/terraform_provider.yml b/.github/workflows/terraform_provider.yml index 45a750bd956..abc9482b96f 100644 --- a/.github/workflows/terraform_provider.yml +++ b/.github/workflows/terraform_provider.yml @@ -218,7 +218,7 @@ jobs: key: ${{ runner.os }}-go-pkg-mod-${{ hashFiles('go.sum') }} - name: Get all changed files id: changed-files - uses: tj-actions/changed-files@v17.2 + uses: tj-actions/changed-files@v18 - name: Get changed packages run: | touch /tmp/dirs_changed_all From ca38585289146f211e00b92d4e9ae6c1d59edc69 Mon Sep 17 00:00:00 2001 From: Jan Willem Logemann Date: Mon, 14 Mar 2022 12:28:58 +0100 Subject: [PATCH 156/229] Fix typos in msk_cluster.html.markdown 2 typos fixed --- website/docs/r/msk_cluster.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/r/msk_cluster.html.markdown b/website/docs/r/msk_cluster.html.markdown index 30b9ae9f445..14d7c31f4aa 100644 --- a/website/docs/r/msk_cluster.html.markdown +++ b/website/docs/r/msk_cluster.html.markdown @@ -266,8 +266,8 @@ In addition to all arguments above, the following attributes are exported: * `current_version` - Current version of the MSK Cluster used for updates, e.g., `K13V1IB3VIYZZH` * `encryption_info.0.encryption_at_rest_kms_key_arn` - The ARN of the KMS key used for encryption at rest of the broker data volumes. * `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). -* `zookeeper_connect_string` - A comma separated list of one or more hostname:port pairs to use to connect to the Apache Zookeeper cluster. The returned values are sorted alphbetically. The AWS API may not return all endpoints, so this value is not guaranteed to be stable across applies. -* `zookeeper_connect_string_tls` - A comma separated list of one or more hostname:port pairs to use to connect to the Apache Zookeeper cluster via TLS. The returned values are sorted alphbetically. The AWS API may not return all endpoints, so this value is not guaranteed to be stable across applies. +* `zookeeper_connect_string` - A comma separated list of one or more hostname:port pairs to use to connect to the Apache Zookeeper cluster. The returned values are sorted alphabetically. The AWS API may not return all endpoints, so this value is not guaranteed to be stable across applies. +* `zookeeper_connect_string_tls` - A comma separated list of one or more hostname:port pairs to use to connect to the Apache Zookeeper cluster via TLS. The returned values are sorted alphabetically. The AWS API may not return all endpoints, so this value is not guaranteed to be stable across applies. ## Timeouts From 8b4c6de95a8756a02234203d62628a7191fb7e04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Mar 2022 11:46:48 +0000 Subject: [PATCH 157/229] build(deps): bump github.com/aws/aws-sdk-go from 1.43.9 to 1.43.17 Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.43.9 to 1.43.17. - [Release notes](https://github.com/aws/aws-sdk-go/releases) - [Changelog](https://github.com/aws/aws-sdk-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-go/compare/v1.43.9...v1.43.17) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 68e459bf4e7..28ad6bad9a6 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.17 require ( github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 - github.com/aws/aws-sdk-go v1.43.9 + github.com/aws/aws-sdk-go v1.43.17 github.com/aws/aws-sdk-go-v2 v1.15.0 github.com/aws/aws-sdk-go-v2/service/route53domains v1.12.0 github.com/beevik/etree v1.1.0 diff --git a/go.sum b/go.sum index cd8c55ebf7d..784511f3661 100644 --- a/go.sum +++ b/go.sum @@ -65,8 +65,8 @@ github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3A github.com/aws/aws-sdk-go v1.25.3/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.42.18/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go v1.42.52/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc= -github.com/aws/aws-sdk-go v1.43.9 h1:k1S/29Bp2QD5ZopnGzIn0Sp63yyt3WH1JRE2OOU3Aig= -github.com/aws/aws-sdk-go v1.43.9/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.43.17 h1:jDPBz1UuTxmyRo0eLgaRiro0fiI1zL7lkscqYxoEDLM= +github.com/aws/aws-sdk-go v1.43.17/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go-v2 v1.15.0 h1:f9kWLNfyCzCB43eupDAk3/XgJ2EpgktiySD6leqs0js= github.com/aws/aws-sdk-go-v2 v1.15.0/go.mod h1:lJYcuZZEHWNIb6ugJjbQY1fykdoobWbOS7kJYb4APoI= github.com/aws/aws-sdk-go-v2/config v1.15.0 h1:cibCYF2c2uq0lsbu0Ggbg8RuGeiHCmXwUlTMS77CiK4= From 8ba99d9ea1ff443c25158e2ce5fff074738ca5c4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Mar 2022 11:46:55 +0000 Subject: [PATCH 158/229] build(deps): bump github.com/aws/aws-sdk-go in /providerlint Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.43.9 to 1.43.17. - [Release notes](https://github.com/aws/aws-sdk-go/releases) - [Changelog](https://github.com/aws/aws-sdk-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-go/compare/v1.43.9...v1.43.17) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- providerlint/go.mod | 2 +- providerlint/go.sum | 4 +- .../aws/aws-sdk-go/aws/endpoints/defaults.go | 178 +++++++++++++++++- providerlint/vendor/modules.txt | 2 +- 4 files changed, 172 insertions(+), 14 deletions(-) diff --git a/providerlint/go.mod b/providerlint/go.mod index 6b1f6ae90c4..17c95f1af08 100644 --- a/providerlint/go.mod +++ b/providerlint/go.mod @@ -3,7 +3,7 @@ module github.com/hashicorp/terraform-provider-aws/providerlint go 1.16 require ( - github.com/aws/aws-sdk-go v1.43.9 + github.com/aws/aws-sdk-go v1.43.17 github.com/bflad/tfproviderlint v0.28.1 github.com/hashicorp/terraform-plugin-sdk/v2 v2.10.1 golang.org/x/tools v0.0.0-20201028111035-eafbe7b904eb diff --git a/providerlint/go.sum b/providerlint/go.sum index 2b8b853c769..61971994936 100644 --- a/providerlint/go.sum +++ b/providerlint/go.sum @@ -70,8 +70,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= github.com/aws/aws-sdk-go v1.25.3/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.43.9 h1:k1S/29Bp2QD5ZopnGzIn0Sp63yyt3WH1JRE2OOU3Aig= -github.com/aws/aws-sdk-go v1.43.9/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.43.17 h1:jDPBz1UuTxmyRo0eLgaRiro0fiI1zL7lkscqYxoEDLM= +github.com/aws/aws-sdk-go v1.43.17/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/bflad/gopaniccheck v0.1.0 h1:tJftp+bv42ouERmUMWLoUn/5bi/iQZjHPznM00cP/bU= github.com/bflad/gopaniccheck v0.1.0/go.mod h1:ZCj2vSr7EqVeDaqVsWN4n2MwdROx1YL+LFo47TSWtsA= github.com/bflad/tfproviderlint v0.28.1 h1:7f54/ynV6/lK5/1EyG7tHtc4sMdjJSEFGjZNRJKwBs8= diff --git a/providerlint/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/providerlint/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go index c565a135563..95f5502d768 100644 --- a/providerlint/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go +++ b/providerlint/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go @@ -2293,15 +2293,60 @@ var awsPartition = partition{ endpointKey{ Region: "eu-west-1", }: endpoint{}, + endpointKey{ + Region: "fips-us-east-1", + }: endpoint{ + Hostname: "apprunner-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-east-2", + }: endpoint{ + Hostname: "apprunner-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "fips-us-west-2", + }: endpoint{ + Hostname: "apprunner-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + Deprecated: boxedTrue, + }, endpointKey{ Region: "us-east-1", }: endpoint{}, + endpointKey{ + Region: "us-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "apprunner-fips.us-east-1.amazonaws.com", + }, endpointKey{ Region: "us-east-2", }: endpoint{}, + endpointKey{ + Region: "us-east-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "apprunner-fips.us-east-2.amazonaws.com", + }, endpointKey{ Region: "us-west-2", }: endpoint{}, + endpointKey{ + Region: "us-west-2", + Variant: fipsVariant, + }: endpoint{ + Hostname: "apprunner-fips.us-west-2.amazonaws.com", + }, }, }, "appstream2": service{ @@ -2828,6 +2873,9 @@ var awsPartition = partition{ endpointKey{ Region: "ap-southeast-2", }: endpoint{}, + endpointKey{ + Region: "ap-southeast-3", + }: endpoint{}, endpointKey{ Region: "ca-central-1", }: endpoint{}, @@ -11021,6 +11069,18 @@ var awsPartition = partition{ }, "ivs": service{ Endpoints: serviceEndpoints{ + endpointKey{ + Region: "ap-northeast-1", + }: endpoint{}, + endpointKey{ + Region: "ap-northeast-2", + }: endpoint{}, + endpointKey{ + Region: "ap-south-1", + }: endpoint{}, + endpointKey{ + Region: "eu-central-1", + }: endpoint{}, endpointKey{ Region: "eu-west-1", }: endpoint{}, @@ -24172,6 +24232,14 @@ var awsusgovPartition = partition{ }, }, "autoscaling": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "autoscaling.{region}.{dnsSuffix}", + }, + }, Endpoints: serviceEndpoints{ endpointKey{ Region: "us-gov-east-1", @@ -24356,20 +24424,40 @@ var awsusgovPartition = partition{ "cloudtrail": service{ Endpoints: serviceEndpoints{ endpointKey{ - Region: "us-gov-east-1", + Region: "fips-us-gov-east-1", }: endpoint{ Hostname: "cloudtrail.us-gov-east-1.amazonaws.com", CredentialScope: credentialScope{ Region: "us-gov-east-1", }, + Deprecated: boxedTrue, }, endpointKey{ - Region: "us-gov-west-1", + Region: "fips-us-gov-west-1", }: endpoint{ Hostname: "cloudtrail.us-gov-west-1.amazonaws.com", CredentialScope: credentialScope{ Region: "us-gov-west-1", }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudtrail.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "cloudtrail.us-gov-west-1.amazonaws.com", }, }, }, @@ -25361,20 +25449,40 @@ var awsusgovPartition = partition{ "events": service{ Endpoints: serviceEndpoints{ endpointKey{ - Region: "us-gov-east-1", + Region: "fips-us-gov-east-1", }: endpoint{ Hostname: "events.us-gov-east-1.amazonaws.com", CredentialScope: credentialScope{ Region: "us-gov-east-1", }, + Deprecated: boxedTrue, }, endpointKey{ - Region: "us-gov-west-1", + Region: "fips-us-gov-west-1", }: endpoint{ Hostname: "events.us-gov-west-1.amazonaws.com", CredentialScope: credentialScope{ Region: "us-gov-west-1", }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "events.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "events.us-gov-west-1.amazonaws.com", }, }, }, @@ -26245,20 +26353,40 @@ var awsusgovPartition = partition{ "logs": service{ Endpoints: serviceEndpoints{ endpointKey{ - Region: "us-gov-east-1", + Region: "fips-us-gov-east-1", }: endpoint{ Hostname: "logs.us-gov-east-1.amazonaws.com", CredentialScope: credentialScope{ Region: "us-gov-east-1", }, + Deprecated: boxedTrue, }, endpointKey{ - Region: "us-gov-west-1", + Region: "fips-us-gov-west-1", }: endpoint{ Hostname: "logs.us-gov-west-1.amazonaws.com", CredentialScope: credentialScope{ Region: "us-gov-west-1", }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "logs.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "logs.us-gov-west-1.amazonaws.com", }, }, }, @@ -27594,25 +27722,55 @@ var awsusgovPartition = partition{ "sns": service{ Endpoints: serviceEndpoints{ endpointKey{ - Region: "us-gov-east-1", + Region: "fips-us-gov-east-1", }: endpoint{ Hostname: "sns.us-gov-east-1.amazonaws.com", CredentialScope: credentialScope{ Region: "us-gov-east-1", }, + Deprecated: boxedTrue, }, endpointKey{ - Region: "us-gov-west-1", + Region: "fips-us-gov-west-1", }: endpoint{ - Hostname: "sns.us-gov-west-1.amazonaws.com", - Protocols: []string{"http", "https"}, + Hostname: "sns.us-gov-west-1.amazonaws.com", CredentialScope: credentialScope{ Region: "us-gov-west-1", }, + Deprecated: boxedTrue, + }, + endpointKey{ + Region: "us-gov-east-1", + }: endpoint{}, + endpointKey{ + Region: "us-gov-east-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sns.us-gov-east-1.amazonaws.com", + }, + endpointKey{ + Region: "us-gov-west-1", + }: endpoint{ + Protocols: []string{"http", "https"}, + }, + endpointKey{ + Region: "us-gov-west-1", + Variant: fipsVariant, + }: endpoint{ + Hostname: "sns.us-gov-west-1.amazonaws.com", + Protocols: []string{"http", "https"}, }, }, }, "sqs": service{ + Defaults: endpointDefaults{ + defaultKey{}: endpoint{}, + defaultKey{ + Variant: fipsVariant, + }: endpoint{ + Hostname: "sqs.{region}.{dnsSuffix}", + }, + }, Endpoints: serviceEndpoints{ endpointKey{ Region: "us-gov-east-1", diff --git a/providerlint/vendor/modules.txt b/providerlint/vendor/modules.txt index aa426fbe1e5..8c0f6602c02 100644 --- a/providerlint/vendor/modules.txt +++ b/providerlint/vendor/modules.txt @@ -4,7 +4,7 @@ github.com/agext/levenshtein github.com/apparentlymart/go-textseg/v12/textseg # github.com/apparentlymart/go-textseg/v13 v13.0.0 github.com/apparentlymart/go-textseg/v13/textseg -# github.com/aws/aws-sdk-go v1.43.9 +# github.com/aws/aws-sdk-go v1.43.17 ## explicit github.com/aws/aws-sdk-go/aws/awserr github.com/aws/aws-sdk-go/aws/endpoints From 0aceea6be1ca9d233e8f469fdbfb04ea50f8c96b Mon Sep 17 00:00:00 2001 From: changelogbot Date: Mon, 14 Mar 2022 11:47:45 +0000 Subject: [PATCH 159/229] Update CHANGELOG.md for #23656 --- CHANGELOG.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f65f87c005e..35492371c43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,32 @@ ## 4.6.0 (Unreleased) +FEATURES: + +* **New Data Source:** `aws_networkmanager_connection` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Data Source:** `aws_networkmanager_connections` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Data Source:** `aws_networkmanager_device` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Data Source:** `aws_networkmanager_devices` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Data Source:** `aws_networkmanager_global_network` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Data Source:** `aws_networkmanager_global_networks` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Data Source:** `aws_networkmanager_link` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Data Source:** `aws_networkmanager_links` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Data Source:** `aws_networkmanager_site` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Data Source:** `aws_networkmanager_sites` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Resource:** `aws_networkmanager_connection` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Resource:** `aws_networkmanager_customer_gateway_association` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Resource:** `aws_networkmanager_device` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Resource:** `aws_networkmanager_global_network` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Resource:** `aws_networkmanager_link` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Resource:** `aws_networkmanager_link_association` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Resource:** `aws_networkmanager_site` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Resource:** `aws_networkmanager_transit_gateway_connect_peer_association` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Resource:** `aws_networkmanager_transit_gateway_registration` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) + ENHANCEMENTS: +* data-source/aws_ec2_transit_gateway_connect_peer: Add `arn` attribute ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) * data_source/aws_redshift_cluster: Add `availability_zone_relocation_enabled` attribute. ([#20812](https://github.com/hashicorp/terraform-provider-aws/issues/20812)) +* resource/aws_ec2_transit_gateway_connect_peer: Add `arn` attribute ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) * resource/aws_redshift_cluster: Add `availability_zone_relocation_enabled` attribute and allow `availability_zone` to be changed in-place. ([#20812](https://github.com/hashicorp/terraform-provider-aws/issues/20812)) ## 4.5.0 (March 11, 2022) From 60b850db6f66b507a95444391eb2144caed25033 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 08:03:02 -0400 Subject: [PATCH 160/229] 'pre_display_banner' -> 'pre_authentication_login_banner' and 'post_display_banner' -> 'post_authentication_login_banner' to match AWS API parameter names. --- internal/service/transfer/server.go | 65 ++++++++++---------- internal/service/transfer/server_test.go | 12 ++-- website/docs/r/transfer_server.html.markdown | 4 +- 3 files changed, 40 insertions(+), 41 deletions(-) diff --git a/internal/service/transfer/server.go b/internal/service/transfer/server.go index 36a6fcf5687..095ea0a5e88 100644 --- a/internal/service/transfer/server.go +++ b/internal/service/transfer/server.go @@ -142,20 +142,6 @@ func ResourceServer() *schema.Resource { ValidateFunc: validation.StringLenBetween(0, 4096), }, - "pre_display_banner": { - Type: schema.TypeString, - Optional: true, - Sensitive: true, - ValidateFunc: validation.StringLenBetween(0, 512), - }, - - "post_display_banner": { - Type: schema.TypeString, - Optional: true, - Sensitive: true, - ValidateFunc: validation.StringLenBetween(0, 512), - }, - "host_key_fingerprint": { Type: schema.TypeString, Computed: true, @@ -181,6 +167,19 @@ func ResourceServer() *schema.Resource { ValidateFunc: verify.ValidARN, }, + "post_authentication_login_banner": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ValidateFunc: validation.StringLenBetween(0, 512), + }, + "pre_authentication_login_banner": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ValidateFunc: validation.StringLenBetween(0, 512), + }, + "protocols": { Type: schema.TypeSet, MinItems: 1, @@ -257,16 +256,6 @@ func resourceServerCreate(d *schema.ResourceData, meta interface{}) error { input.IdentityProviderDetails.Function = aws.String(v.(string)) } - if v, ok := d.GetOk("pre_display_banner"); ok { - input.PreAuthenticationLoginBanner = aws.String(v.(string)) - - } - - if v, ok := d.GetOk("post_display_banner"); ok { - input.PostAuthenticationLoginBanner = aws.String(v.(string)) - - } - if v, ok := d.GetOk("host_key"); ok { input.HostKey = aws.String(v.(string)) } @@ -287,6 +276,14 @@ func resourceServerCreate(d *schema.ResourceData, meta interface{}) error { input.LoggingRole = aws.String(v.(string)) } + if v, ok := d.GetOk("post_authentication_login_banner"); ok { + input.PostAuthenticationLoginBanner = aws.String(v.(string)) + } + + if v, ok := d.GetOk("pre_authentication_login_banner"); ok { + input.PreAuthenticationLoginBanner = aws.String(v.(string)) + } + if v, ok := d.GetOk("protocols"); ok && v.(*schema.Set).Len() > 0 { input.Protocols = flex.ExpandStringSet(v.(*schema.Set)) } @@ -402,8 +399,6 @@ func resourceServerRead(d *schema.ResourceData, meta interface{}) error { } else { d.Set("function", "") } - d.Set("pre_display_banner", output.PreAuthenticationLoginBanner) - d.Set("post_display_banner", output.PostAuthenticationLoginBanner) d.Set("host_key_fingerprint", output.HostKeyFingerprint) d.Set("identity_provider_type", output.IdentityProviderType) if output.IdentityProviderDetails != nil { @@ -412,6 +407,8 @@ func resourceServerRead(d *schema.ResourceData, meta interface{}) error { d.Set("invocation_role", "") } d.Set("logging_role", output.LoggingRole) + d.Set("post_authentication_login_banner", output.PostAuthenticationLoginBanner) + d.Set("pre_authentication_login_banner", output.PreAuthenticationLoginBanner) d.Set("protocols", aws.StringValueSlice(output.Protocols)) d.Set("security_policy_name", output.SecurityPolicyName) if output.IdentityProviderDetails != nil { @@ -547,14 +544,6 @@ func resourceServerUpdate(d *schema.ResourceData, meta interface{}) error { offlineUpdate = true } - if d.HasChange("pre_display_banner") { - input.PreAuthenticationLoginBanner = aws.String(d.Get("pre_display_banner").(string)) - } - - if d.HasChange("post_display_banner") { - input.PostAuthenticationLoginBanner = aws.String(d.Get("post_display_banner").(string)) - } - if d.HasChange("host_key") { if attr, ok := d.GetOk("host_key"); ok { input.HostKey = aws.String(attr.(string)) @@ -587,6 +576,14 @@ func resourceServerUpdate(d *schema.ResourceData, meta interface{}) error { input.LoggingRole = aws.String(d.Get("logging_role").(string)) } + if d.HasChange("post_authentication_login_banner") { + input.PostAuthenticationLoginBanner = aws.String(d.Get("post_authentication_login_banner").(string)) + } + + if d.HasChange("pre_authentication_login_banner") { + input.PreAuthenticationLoginBanner = aws.String(d.Get("pre_authentication_login_banner").(string)) + } + if d.HasChange("protocols") { input.Protocols = flex.ExpandStringSet(d.Get("protocols").(*schema.Set)) } diff --git a/internal/service/transfer/server_test.go b/internal/service/transfer/server_test.go index 78123078624..c452e53250c 100644 --- a/internal/service/transfer/server_test.go +++ b/internal/service/transfer/server_test.go @@ -56,6 +56,8 @@ func testAccServer_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "identity_provider_type", "SERVICE_MANAGED"), resource.TestCheckResourceAttr(resourceName, "invocation_role", ""), resource.TestCheckResourceAttr(resourceName, "logging_role", ""), + resource.TestCheckResourceAttr(resourceName, "post_authentication_login_banner", ""), + resource.TestCheckResourceAttr(resourceName, "pre_authentication_login_banner", ""), resource.TestCheckResourceAttr(resourceName, "protocols.#", "1"), resource.TestCheckTypeSetElemAttr(resourceName, "protocols.*", "SFTP"), resource.TestCheckResourceAttr(resourceName, "security_policy_name", "TransferSecurityPolicy-2018-11"), @@ -941,7 +943,7 @@ func testAccServer_lambdaFunction(t *testing.T) { }) } -func TestAccTransferServer_DisplayBanners(t *testing.T) { +func TestAccTransferServer_AuthenticationLoginBanners(t *testing.T) { var conf transfer.DescribedServer resourceName := "aws_transfer_server.test" @@ -955,8 +957,8 @@ func TestAccTransferServer_DisplayBanners(t *testing.T) { Config: testAccServerDisplayBannersConfig(), Check: resource.ComposeTestCheckFunc( testAccCheckServerExists(resourceName, &conf), - resource.TestCheckResourceAttr(resourceName, "pre_display_banner", "This system is for the use of authorized users only"), - resource.TestCheckResourceAttr(resourceName, "post_display_banner", "This system is for the use of authorized users only"), + resource.TestCheckResourceAttr(resourceName, "post_authentication_login_banner", "This system is for the use of authorized users only - post"), + resource.TestCheckResourceAttr(resourceName, "pre_authentication_login_banner", "This system is for the use of authorized users only - pre"), ), }, { @@ -1225,8 +1227,8 @@ resource "aws_transfer_server" "test" {} func testAccServerDisplayBannersConfig() string { return ` resource "aws_transfer_server" "test" { - pre_display_banner = "This system is for the use of authorized users only" - post_display_banner = "This system is for the use of authorized users only" + pre_authentication_login_banner = "This system is for the use of authorized users only - pre" + post_authentication_login_banner = "This system is for the use of authorized users only - post" } ` } diff --git a/website/docs/r/transfer_server.html.markdown b/website/docs/r/transfer_server.html.markdown index 435247cfc3c..dbdd8e63fa4 100644 --- a/website/docs/r/transfer_server.html.markdown +++ b/website/docs/r/transfer_server.html.markdown @@ -103,8 +103,8 @@ The following arguments are supported: * `function` - (Optional) The ARN for a lambda function to use for the Identity provider. * `logging_role` - (Optional) Amazon Resource Name (ARN) of an IAM role that allows the service to write your SFTP users’ activity to your Amazon CloudWatch logs for monitoring and auditing purposes. * `force_destroy` - (Optional) A boolean that indicates all users associated with the server should be deleted so that the Server can be destroyed without error. The default value is `false`. This option only applies to servers configured with a `SERVICE_MANAGED` `identity_provider_type`. -* `pre_display_banner`- (Optional) Specify a string to display when users connect to a server. This string is displayed before the user authenticates. -* `post_display_banner`- (Optional) Specify a string to display when users connect to a server. This string is displayed after the user authenticates. The SFTP protocol does not support post-authentication display banners. +* `post_authentication_login_banner`- (Optional) Specify a string to display when users connect to a server. This string is displayed after the user authenticates. The SFTP protocol does not support post-authentication display banners. +* `pre_authentication_login_banner`- (Optional) Specify a string to display when users connect to a server. This string is displayed before the user authenticates. * `security_policy_name` - (Optional) Specifies the name of the security policy that is attached to the server. Possible values are `TransferSecurityPolicy-2018-11`, `TransferSecurityPolicy-2020-06`, and `TransferSecurityPolicy-FIPS-2020-06`. Default value is: `TransferSecurityPolicy-2018-11`. * `tags` - (Optional) A map of tags to assign to the resource. If configured with a provider [`default_tags` configuration block](https://www.terraform.io/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. From 9abe7115a77f7ed7ac32e39ec3ed276fb71c7b0f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 08:04:26 -0400 Subject: [PATCH 161/229] Add CHANGELOG entry. --- .changelog/23631.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/23631.txt diff --git a/.changelog/23631.txt b/.changelog/23631.txt new file mode 100644 index 00000000000..4878b643f0e --- /dev/null +++ b/.changelog/23631.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_transfer_server: Add `pre_authentication_login_banner` and `post_authentication_login_banner` arguments +``` \ No newline at end of file From 1728e9a81741f57473f3b6bf26f46f368ebb574a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 08:05:53 -0400 Subject: [PATCH 162/229] 'TestAccTransferServer_AuthenticationLoginBanners' -> 'testAccTransferServer_AuthenticationLoginBanners' and serialize test. --- internal/service/transfer/server_test.go | 2 +- internal/service/transfer/transfer_test.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/service/transfer/server_test.go b/internal/service/transfer/server_test.go index c452e53250c..3e5a1e2e379 100644 --- a/internal/service/transfer/server_test.go +++ b/internal/service/transfer/server_test.go @@ -943,7 +943,7 @@ func testAccServer_lambdaFunction(t *testing.T) { }) } -func TestAccTransferServer_AuthenticationLoginBanners(t *testing.T) { +func testAccTransferServer_AuthenticationLoginBanners(t *testing.T) { var conf transfer.DescribedServer resourceName := "aws_transfer_server.test" diff --git a/internal/service/transfer/transfer_test.go b/internal/service/transfer/transfer_test.go index 30b1a3ea6fd..a4a6b1f400b 100644 --- a/internal/service/transfer/transfer_test.go +++ b/internal/service/transfer/transfer_test.go @@ -17,6 +17,7 @@ func TestAccTransfer_serial(t *testing.T) { "disappears": testAccServer_disappears, "APIGateway": testAccServer_apiGateway, "APIGatewayForceDestroy": testAccServer_apiGateway_forceDestroy, + "AuthenticationLoginBanners": testAccTransferServer_AuthenticationLoginBanners, "DirectoryService": testAccServer_directoryService, "Domain": testAccServer_domain, "ForceDestroy": testAccServer_forceDestroy, From fe81ffe4218ea00bc36d05138b3e77d33020ce12 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 08:07:11 -0400 Subject: [PATCH 163/229] Cosmetics. --- internal/service/transfer/server.go | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/internal/service/transfer/server.go b/internal/service/transfer/server.go index 095ea0a5e88..8460b36de22 100644 --- a/internal/service/transfer/server.go +++ b/internal/service/transfer/server.go @@ -50,18 +50,15 @@ func ResourceServer() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "certificate": { Type: schema.TypeString, Optional: true, ValidateFunc: verify.ValidARN, }, - "directory_id": { Type: schema.TypeString, Optional: true, }, - "domain": { Type: schema.TypeString, Optional: true, @@ -69,12 +66,10 @@ func ResourceServer() *schema.Resource { Default: transfer.DomainS3, ValidateFunc: validation.StringInSlice(transfer.Domain_Values(), false), }, - "endpoint": { Type: schema.TypeString, Computed: true, }, - "endpoint_details": { Type: schema.TypeList, Optional: true, @@ -115,38 +110,32 @@ func ResourceServer() *schema.Resource { }, }, }, - "endpoint_type": { Type: schema.TypeString, Optional: true, Default: transfer.EndpointTypePublic, ValidateFunc: validation.StringInSlice(transfer.EndpointType_Values(), false), }, - "force_destroy": { Type: schema.TypeBool, Optional: true, Default: false, }, - "function": { Type: schema.TypeString, Optional: true, ValidateFunc: verify.ValidARN, }, - "host_key": { Type: schema.TypeString, Optional: true, Sensitive: true, ValidateFunc: validation.StringLenBetween(0, 4096), }, - "host_key_fingerprint": { Type: schema.TypeString, Computed: true, }, - "identity_provider_type": { Type: schema.TypeString, Optional: true, @@ -154,19 +143,16 @@ func ResourceServer() *schema.Resource { Default: transfer.IdentityProviderTypeServiceManaged, ValidateFunc: validation.StringInSlice(transfer.IdentityProviderType_Values(), false), }, - "invocation_role": { Type: schema.TypeString, Optional: true, ValidateFunc: verify.ValidARN, }, - "logging_role": { Type: schema.TypeString, Optional: true, ValidateFunc: verify.ValidARN, }, - "post_authentication_login_banner": { Type: schema.TypeString, Optional: true, @@ -179,7 +165,6 @@ func ResourceServer() *schema.Resource { Sensitive: true, ValidateFunc: validation.StringLenBetween(0, 512), }, - "protocols": { Type: schema.TypeSet, MinItems: 1, @@ -191,17 +176,14 @@ func ResourceServer() *schema.Resource { ValidateFunc: validation.StringInSlice(transfer.Protocol_Values(), false), }, }, - "security_policy_name": { Type: schema.TypeString, Optional: true, Default: SecurityPolicyName2018_11, ValidateFunc: validation.StringInSlice(SecurityPolicyName_Values(), false), }, - "tags": tftags.TagsSchema(), "tags_all": tftags.TagsSchemaComputed(), - "url": { Type: schema.TypeString, Optional: true, From b3aa559fd35226a952d6e2341805ec2d3a69775a Mon Sep 17 00:00:00 2001 From: Ido Markovitz Date: Mon, 14 Mar 2022 14:12:58 +0200 Subject: [PATCH 164/229] fix(kafka): add customize diff func to handle revision change --- internal/service/kafka/configuration.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/internal/service/kafka/configuration.go b/internal/service/kafka/configuration.go index 9cfc3f816b0..b2fb0120ea7 100644 --- a/internal/service/kafka/configuration.go +++ b/internal/service/kafka/configuration.go @@ -1,12 +1,14 @@ package kafka import ( + "context" "fmt" "log" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/kafka" "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/flex" @@ -22,6 +24,14 @@ func ResourceConfiguration() *schema.Resource { Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, + CustomizeDiff: customdiff.Sequence( + func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error { + if diff.HasChange("server_properties") { + return diff.SetNewComputed("latest_revision") + } + return nil + }, + ), Schema: map[string]*schema.Schema{ "arn": { From 5619c8f0234d44f0e8081ab4ee2faaeaf57b64c7 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 08:20:09 -0400 Subject: [PATCH 165/229] Revert "r/aws_gamelift_game_server_group: Fix formatting" This reverts commit 522baf0b1b8168594dbb4d8e3ebc925b81fd5a41. --- aws/resource_aws_gamelift_game_server_group_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aws/resource_aws_gamelift_game_server_group_test.go b/aws/resource_aws_gamelift_game_server_group_test.go index 30c7120b226..59c614a6805 100644 --- a/aws/resource_aws_gamelift_game_server_group_test.go +++ b/aws/resource_aws_gamelift_game_server_group_test.go @@ -926,7 +926,7 @@ resource "aws_gamelift_game_server_group" "test" { for_each = slice(tolist(data.aws_ec2_instance_type_offerings.available.instance_types), 0, 2) content { - instance_type = instance_definition.value + instance_type = instance_definition.value weighted_capacity = %[2]q } } @@ -1024,7 +1024,7 @@ resource "aws_gamelift_game_server_group" "test" { } launch_template { - id = aws_launch_template.test.id + id = aws_launch_template.test.id version = 1 } @@ -1142,7 +1142,7 @@ func testAccGameliftGameServerGroupConfigGameServerProtectionPolicy(rName string testAccGameliftGameServerGroupLaunchTemplateConfig(rName), fmt.Sprintf(` resource "aws_gamelift_game_server_group" "test" { - game_server_group_name = %[1]q + game_server_group_name = %[1]q game_server_protection_policy = %[2]q dynamic "instance_definition" { From c65f369047e8ec36edfa07953e2086ab7b3299ba Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 08:20:19 -0400 Subject: [PATCH 166/229] Revert "r/aws_gamelift_game_server_group: Fix formatting" This reverts commit 0168e5fa49dd5083d1b509b8b6166b08b0e5f3ba. --- ...rce_aws_gamelift_game_server_group_test.go | 26 ++++----- .../gamelift_game_server_group.html.markdown | 54 +++++++++---------- 2 files changed, 38 insertions(+), 42 deletions(-) diff --git a/aws/resource_aws_gamelift_game_server_group_test.go b/aws/resource_aws_gamelift_game_server_group_test.go index 59c614a6805..6171796f7c4 100644 --- a/aws/resource_aws_gamelift_game_server_group_test.go +++ b/aws/resource_aws_gamelift_game_server_group_test.go @@ -660,7 +660,7 @@ func testAccCheckGameliftGameServerGroupExists(resourceName string) resource.Tes func testAccGameliftGameServerGroupIamConfig(rName string, name string) string { return fmt.Sprintf(` -data "aws_partition" %[2]q {} +data "aws_partition" "current" {} resource "aws_iam_role" %[2]q { assume_role_policy = <<-EOF @@ -685,7 +685,7 @@ resource "aws_iam_role" %[2]q { } resource "aws_iam_role_policy_attachment" %[2]q { - policy_arn = "arn:${data.aws_partition.%[2]s.partition}:iam::aws:policy/GameLiftGameServerGroupPolicy" + policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/GameLiftGameServerGroupPolicy" role = aws_iam_role.%[2]s.name } `, rName, name) @@ -695,7 +695,7 @@ func testAccGameliftGameServerGroupLaunchTemplateConfig(rName string) string { return fmt.Sprintf(` resource "aws_launch_template" "test" { image_id = data.aws_ami.amzn-ami-minimal-hvm-ebs.id - name = %[1]q + name = %[1]q } `, rName) } @@ -704,7 +704,7 @@ func testAccGameliftGameServerGroupInstanceTypeOfferingsConfig() string { return ` data "aws_ec2_instance_type_offerings" "available" { filter { - name = "instance-type" + name = "instance-type" values = ["c5a.large", "c5a.2xlarge", "c5.large", "c5.2xlarge", "m4.large", "m4.2xlarge", "m5a.large", "m5a.2xlarge", "m5.large", "m5.2xlarge"] } } @@ -826,7 +826,7 @@ func testAccGameliftGameServerGroupConfigBalancingStrategy(rName string, balanci testAccGameliftGameServerGroupLaunchTemplateConfig(rName), fmt.Sprintf(` resource "aws_gamelift_game_server_group" "test" { - balancing_strategy = %[2]q + balancing_strategy = %[2]q game_server_group_name = %[1]q dynamic "instance_definition" { @@ -892,7 +892,7 @@ resource "aws_gamelift_game_server_group" "test" { game_server_group_name = %[1]q dynamic "instance_definition" { - for_each = slice(tolist(data.aws_ec2_instance_type_offerings.available.instance_types), 0, %[2]d) + for_each = slice(tolist(data.aws_ec2_instance_type_offerings.available.instance_types), 0, %[2]d) content { instance_type = instance_definition.value @@ -923,7 +923,7 @@ resource "aws_gamelift_game_server_group" "test" { game_server_group_name = %[1]q dynamic "instance_definition" { - for_each = slice(tolist(data.aws_ec2_instance_type_offerings.available.instance_types), 0, 2) + for_each = slice(tolist(data.aws_ec2_instance_type_offerings.available.instance_types), 0, 2) content { instance_type = instance_definition.value @@ -1093,7 +1093,7 @@ resource "aws_gamelift_game_server_group" "test" { max_size = 2 min_size = %[2]s role_arn = aws_iam_role.test.arn - + depends_on = [aws_iam_role_policy_attachment.test] } `, rName, minSize)) @@ -1180,7 +1180,7 @@ resource "aws_gamelift_game_server_group" "test" { for_each = data.aws_ec2_instance_type_offerings.available.instance_types content { - instance_type = instance_definition.key + instance_type = instance_definition.key } } @@ -1219,7 +1219,7 @@ resource "aws_gamelift_game_server_group" "test" { for_each = data.aws_ec2_instance_type_offerings.available.instance_types content { - instance_type = instance_definition.key + instance_type = instance_definition.key } } @@ -1227,9 +1227,9 @@ resource "aws_gamelift_game_server_group" "test" { id = aws_launch_template.test.id } - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.test.arn + max_size = 1 + min_size = 1 + role_arn = aws_iam_role.test.arn vpc_subnets = slice(tolist(data.aws_subnet_ids.test.ids), 0, %[2]d) depends_on = [aws_iam_role_policy_attachment.test] diff --git a/website/docs/r/gamelift_game_server_group.html.markdown b/website/docs/r/gamelift_game_server_group.html.markdown index 56d4ef165f6..b72a9d42ac8 100644 --- a/website/docs/r/gamelift_game_server_group.html.markdown +++ b/website/docs/r/gamelift_game_server_group.html.markdown @@ -3,7 +3,7 @@ subcategory: "Gamelift" layout: "aws" page_title: "AWS: aws_gamelift_game_server_group" description: |- - Provides a Gamelift Game Server Group resource. +Provides a Gamelift Game Server Group resource. --- # Resource: aws_gamelift_game_server_group @@ -52,22 +52,22 @@ resource "aws_gamelift_game_server_group" "example" { } } - balancing_strategy = "SPOT_ONLY" - game_server_group_name = "example" + balancing_strategy = "SPOT_ONLY" + game_server_group_name = "example" game_server_protection_policy = "FULL_PROTECTION" instance_definition { - instance_type = "c5.large" + instance_type = "c5.large" weighted_capacity = "1" } instance_definition { - instance_type = "c5.2xlarge" + instance_type = "c5.2xlarge" weighted_capacity = "2" } launch_template { - id = aws_launch_template.example.id + id = aws_launch_template.example.id version = "1" } @@ -80,7 +80,7 @@ resource "aws_gamelift_game_server_group" "example" { } vpc_subnets = [ - "subnet-12345678", + "subnet-12345678", "subnet-23456789" ] @@ -91,7 +91,6 @@ resource "aws_gamelift_game_server_group" "example" { ``` ### Example IAM Role for Gamelift Game Server Group - ```hcl data "aws_partition" "current" {} @@ -119,7 +118,7 @@ resource "aws_iam_role" "example" { resource "aws_iam_role_policy_attachment" "example" { policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/GameLiftGameServerGroupPolicy" - role = aws_iam_role.example.name + role = aws_iam_role.example.name } ``` @@ -127,19 +126,19 @@ resource "aws_iam_role_policy_attachment" "example" { The following arguments are supported: -* `balancing_strategy` - (Optional) Indicates how GameLift FleetIQ balances the use of Spot Instances and On-Demand Instances. +* `balancing_strategy` - (Optional) Indicates how GameLift FleetIQ balances the use of Spot Instances and On-Demand Instances. Valid values: `SPOT_ONLY`, `SPOT_PREFERRED`, `ON_DEMAND_ONLY`. Defaults to `SPOT_PREFERRED`. -* `game_server_group_name` - (Required) Name of the game server group. +* `game_server_group_name` - (Required) Name of the game server group. This value is used to generate unique ARN identifiers for the EC2 Auto Scaling group and the GameLift FleetIQ game server group. -* `game_server_protection_policy` - (Optional) Indicates whether instances in the game server group are protected from early termination. - Unprotected instances that have active game servers running might be terminated during a scale-down event, - causing players to be dropped from the game. - Protected instances cannot be terminated while there are active game servers running except in the event +* `game_server_protection_policy` - (Optional) Indicates whether instances in the game server group are protected from early termination. + Unprotected instances that have active game servers running might be terminated during a scale-down event, + causing players to be dropped from the game. + Protected instances cannot be terminated while there are active game servers running except in the event of a forced game server group deletion. Valid values: `NO_PROTECTION`, `FULL_PROTECTION`. Defaults to `NO_PROTECTION`. -* `max_size` - (Required) The maximum number of instances allowed in the EC2 Auto Scaling group. +* `max_size` - (Required) The maximum number of instances allowed in the EC2 Auto Scaling group. During automatic scaling events, GameLift FleetIQ and EC2 do not scale up the group above this maximum. -* `min_size` - (Required) The minimum number of instances allowed in the EC2 Auto Scaling group. +* `min_size` - (Required) The minimum number of instances allowed in the EC2 Auto Scaling group. During automatic scaling events, GameLift FleetIQ and EC2 do not scale down the group below this minimum. * `role_arn` - (Required) ARN for an IAM role that allows Amazon GameLift to access your EC2 Auto Scaling groups. * `tags` - (Optional) Key-value map of resource tags @@ -147,38 +146,34 @@ The following arguments are supported: By default, all GameLift FleetIQ-supported Availability Zones are used. ### `auto_scaling_policy` - Configuration settings to define a scaling policy for the Auto Scaling group that is optimized for game hosting. -The scaling policy uses the metric `PercentUtilizedGameServers` to maintain a buffer of idle game servers that +The scaling policy uses the metric `PercentUtilizedGameServers` to maintain a buffer of idle game servers that can immediately accommodate new games and players. -* `estimated_instance_warmup` - (Optional) Length of time, in seconds, it takes for a new instance to start +* `estimated_instance_warmup` - (Optional) Length of time, in seconds, it takes for a new instance to start new game server processes and register with GameLift FleetIQ. - Specifying a warm-up time can be useful, particularly with game servers that take a long time to start up, + Specifying a warm-up time can be useful, particularly with game servers that take a long time to start up, because it avoids prematurely starting new instances. Defaults to `60`. #### `target_tracking_configuration` - Settings for a target-based scaling policy applied to Auto Scaling group. -These settings are used to create a target-based policy that tracks the GameLift FleetIQ metric `PercentUtilizedGameServers` +These settings are used to create a target-based policy that tracks the GameLift FleetIQ metric `PercentUtilizedGameServers` and specifies a target value for the metric. * `target_value` - (Required) Desired value to use with a game server group target-based scaling policy. ### `instance_definition` - The EC2 instance types and sizes to use in the Auto Scaling group. The instance definitions must specify at least two different instance types that are supported by GameLift FleetIQ. * `instance_type` - (Required) An EC2 instance type. -* `weighted_capacity` - (Optional) Instance weighting that indicates how much this instance type contributes - to the total capacity of a game server group. - Instance weights are used by GameLift FleetIQ to calculate the instance type's cost per unit hour and better identify +* `weighted_capacity` - (Optional) Instance weighting that indicates how much this instance type contributes + to the total capacity of a game server group. + Instance weights are used by GameLift FleetIQ to calculate the instance type's cost per unit hour and better identify the most cost-effective options. ### `launch_template` - -The EC2 launch template that contains configuration settings and game server code to be deployed to all instances in the game server group. +The EC2 launch template that contains configuration settings and game server code to be deployed to all instances in the game server group. You can specify the template using either the template name or ID. * `id` - (Optional) A unique identifier for an existing EC2 launch template. @@ -193,6 +188,7 @@ In addition to all arguments above, the following attributes are exported: * `arn` - The ARN of the Gamelift Game Server Group. * `auto_scaling_group_arn` - The ARN of the created EC2 Auto Scaling group. + ## Timeouts `aws_gamelift_game_server_group` provides the following From ad20d6f13373499d8c6ddcf57ef2bb5692c3cc9b Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 08:20:28 -0400 Subject: [PATCH 167/229] Revert "r/aws_gamelift_game_server_group: Add changelog" This reverts commit 4a56c1e38cc2258616e4c67adba394fbbc5729e4. --- .changelog/18003.txt | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .changelog/18003.txt diff --git a/.changelog/18003.txt b/.changelog/18003.txt deleted file mode 100644 index 7827744e5db..00000000000 --- a/.changelog/18003.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:new-resource -aws_gamelift_game_server_group -``` From 76c6bd78b80369db29f1874086a9a73a181ea0a0 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 08:20:36 -0400 Subject: [PATCH 168/229] Revert "r/aws_gamelift_game_server_group: New resource" This reverts commit 173692b56a5462509ce40f31d344bcc463eb7a10. --- .../service/gamelift/waiter/status.go | 33 - .../service/gamelift/waiter/waiter.go | 51 - aws/provider.go | 1 - ...resource_aws_gamelift_game_server_group.go | 531 ------- ...rce_aws_gamelift_game_server_group_test.go | 1238 ----------------- .../gamelift_game_server_group.html.markdown | 206 --- 6 files changed, 2060 deletions(-) delete mode 100644 aws/internal/service/gamelift/waiter/status.go delete mode 100644 aws/internal/service/gamelift/waiter/waiter.go delete mode 100644 aws/resource_aws_gamelift_game_server_group.go delete mode 100644 aws/resource_aws_gamelift_game_server_group_test.go delete mode 100644 website/docs/r/gamelift_game_server_group.html.markdown diff --git a/aws/internal/service/gamelift/waiter/status.go b/aws/internal/service/gamelift/waiter/status.go deleted file mode 100644 index 99bfe16e2bf..00000000000 --- a/aws/internal/service/gamelift/waiter/status.go +++ /dev/null @@ -1,33 +0,0 @@ -package waiter - -import ( - "errors" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/gamelift" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" -) - -func GameServerGroupState(conn *gamelift.GameLift, gameServerGroupID string) resource.StateRefreshFunc { - return func() (interface{}, string, error) { - output, err := conn.DescribeGameServerGroup(&gamelift.DescribeGameServerGroupInput{ - GameServerGroupName: aws.String(gameServerGroupID), - }) - - if err != nil { - return nil, "", err - } - - if output == nil || output.GameServerGroup == nil { - return nil, "", nil - } - - status := aws.StringValue(output.GameServerGroup.Status) - - if status == gamelift.GameServerGroupStatusError { - return nil, status, errors.New(aws.StringValue(output.GameServerGroup.StatusReason)) - } - - return output.GameServerGroup, status, nil - } -} diff --git a/aws/internal/service/gamelift/waiter/waiter.go b/aws/internal/service/gamelift/waiter/waiter.go deleted file mode 100644 index f037231236e..00000000000 --- a/aws/internal/service/gamelift/waiter/waiter.go +++ /dev/null @@ -1,51 +0,0 @@ -package waiter - -import ( - "time" - - "github.com/aws/aws-sdk-go/service/gamelift" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" -) - -func GameServerGroupActive(conn *gamelift.GameLift, gameServerGroupID string, timeout time.Duration) (*gamelift.GameServerGroup, error) { - stateConf := &resource.StateChangeConf{ - Pending: []string{ - gamelift.GameServerGroupStatusNew, - gamelift.GameServerGroupStatusActivating, - }, - Target: []string{ - gamelift.GameServerGroupStatusActive, - }, - Refresh: GameServerGroupState(conn, gameServerGroupID), - Timeout: timeout, - } - - outputRaw, err := stateConf.WaitForState() - - if v, ok := outputRaw.(*gamelift.GameServerGroup); ok { - return v, err - } - - return nil, err -} - -func GameServerGroupDeleted(conn *gamelift.GameLift, gameServerGroupID string, timeout time.Duration) (*gamelift.GameServerGroup, error) { - stateConf := &resource.StateChangeConf{ - Pending: []string{ - gamelift.GameServerGroupStatusDeleteScheduled, - gamelift.GameServerGroupStatusDeleting, - gamelift.GameServerGroupStatusDeleted, - }, - Target: []string{}, - Refresh: GameServerGroupState(conn, gameServerGroupID), - Timeout: timeout, - } - - outputRaw, err := stateConf.WaitForState() - - if v, ok := outputRaw.(*gamelift.GameServerGroup); ok { - return v, err - } - - return nil, err -} diff --git a/aws/provider.go b/aws/provider.go index c71ded1d3d3..5de81c4636c 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -688,7 +688,6 @@ func Provider() *schema.Provider { "aws_gamelift_alias": resourceAwsGameliftAlias(), "aws_gamelift_build": resourceAwsGameliftBuild(), "aws_gamelift_fleet": resourceAwsGameliftFleet(), - "aws_gamelift_game_server_group": resourceAwsGameliftGameServerGroup(), "aws_gamelift_game_session_queue": resourceAwsGameliftGameSessionQueue(), "aws_glacier_vault": resourceAwsGlacierVault(), "aws_glacier_vault_lock": resourceAwsGlacierVaultLock(), diff --git a/aws/resource_aws_gamelift_game_server_group.go b/aws/resource_aws_gamelift_game_server_group.go deleted file mode 100644 index 4406f91a8de..00000000000 --- a/aws/resource_aws_gamelift_game_server_group.go +++ /dev/null @@ -1,531 +0,0 @@ -package aws - -import ( - "fmt" - "log" - "strings" - "time" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/autoscaling" - "github.com/aws/aws-sdk-go/service/gamelift" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" - "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/gamelift/waiter" -) - -func resourceAwsGameliftGameServerGroup() *schema.Resource { - return &schema.Resource{ - Create: resourceAwsGameliftGameServerGroupCreate, - Read: resourceAwsGameliftGameServerGroupRead, - Update: resourceAwsGameliftGameServerGroupUpdate, - Delete: resourceAwsGameliftGameServerGroupDelete, - Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, - }, - - Timeouts: &schema.ResourceTimeout{ - Create: schema.DefaultTimeout(10 * time.Minute), - Delete: schema.DefaultTimeout(30 * time.Minute), - }, - - Schema: map[string]*schema.Schema{ - "arn": { - Type: schema.TypeString, - Computed: true, - }, - "auto_scaling_group_arn": { - Type: schema.TypeString, - Computed: true, - }, - "auto_scaling_policy": { - Type: schema.TypeList, - Optional: true, - ForceNew: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "estimated_instance_warmup": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - ForceNew: true, - ValidateFunc: validation.IntAtLeast(1), - }, - "target_tracking_configuration": { - Type: schema.TypeList, - Required: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "target_value": { - Type: schema.TypeFloat, - Required: true, - ForceNew: true, - ValidateFunc: validation.FloatAtLeast(0), - }, - }, - }, - }, - }, - }, - }, - "balancing_strategy": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateFunc: validation.StringInSlice(gamelift.BalancingStrategy_Values(), false), - }, - "game_server_group_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringLenBetween(1, 128), - }, - "game_server_protection_policy": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateFunc: validation.StringInSlice(gamelift.GameServerProtectionPolicy_Values(), false), - }, - "instance_definition": { - Type: schema.TypeSet, - Required: true, - MinItems: 2, - MaxItems: 20, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "instance_type": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice(gamelift.GameServerGroupInstanceType_Values(), false), - }, - "weighted_capacity": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringLenBetween(1, 3), - }, - }, - }, - }, - "launch_template": { - Type: schema.TypeList, - Required: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ConflictsWith: []string{"launch_template.0.name"}, - ValidateFunc: validateLaunchTemplateId, - }, - "name": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ConflictsWith: []string{"launch_template.0.id"}, - ValidateFunc: validateLaunchTemplateName, - }, - "version": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - ValidateFunc: validation.StringLenBetween(1, 128), - }, - }, - }, - }, - "max_size": { - Type: schema.TypeInt, - Required: true, - ForceNew: true, - ValidateFunc: validation.IntAtLeast(1), - }, - "min_size": { - Type: schema.TypeInt, - Required: true, - ForceNew: true, - ValidateFunc: validation.IntAtLeast(0), - }, - "role_arn": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validateArn, - }, - "tags": tagsSchema(), - "vpc_subnets": { - Type: schema.TypeSet, - Optional: true, - ForceNew: true, - MaxItems: 20, - Elem: &schema.Schema{ - Type: schema.TypeString, - ValidateFunc: validation.StringLenBetween(15, 24), - }, - }, - }, - } -} - -func resourceAwsGameliftGameServerGroupCreate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).gameliftconn - - gameServerGroupName := d.Get("game_server_group_name").(string) - - input := gamelift.CreateGameServerGroupInput{ - GameServerGroupName: aws.String(gameServerGroupName), - InstanceDefinitions: expandGameliftInstanceDefinitions(d.Get("instance_definition").(*schema.Set).List()), - LaunchTemplate: expandGameliftLaunchTemplateSpecification(d.Get("launch_template").([]interface{})[0].(map[string]interface{})), - MaxSize: aws.Int64(int64(d.Get("max_size").(int))), - MinSize: aws.Int64(int64(d.Get("min_size").(int))), - RoleArn: aws.String(d.Get("role_arn").(string)), - Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().GameliftTags(), - } - - if v, ok := d.GetOk("auto_scaling_policy"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - input.AutoScalingPolicy = expandGameliftGameServerGroupAutoScalingPolicy(v.([]interface{})[0].(map[string]interface{})) - } - - if v, ok := d.GetOk("balancing_strategy"); ok { - input.BalancingStrategy = aws.String(v.(string)) - } - - if v, ok := d.GetOk("game_server_protection_policy"); ok { - input.GameServerProtectionPolicy = aws.String(v.(string)) - } - - if v, ok := d.GetOk("vpc_subnets"); ok && v.(*schema.Set).Len() > 0 { - input.VpcSubnets = expandStringSet(v.(*schema.Set)) - } - - _, err := conn.CreateGameServerGroup(&input) - - if err != nil { - return fmt.Errorf("error creating GameLift Game Server Group: %w", err) - } - - d.SetId(gameServerGroupName) - - if _, err := waiter.GameServerGroupActive(conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { - return fmt.Errorf("error waiting for Gamelift Game Server Group (%s) to be active: %w", d.Id(), err) - } - - return resourceAwsGameliftGameServerGroupRead(d, meta) -} - -func resourceAwsGameliftGameServerGroupRead(d *schema.ResourceData, meta interface{}) error { - autoscalingconn := meta.(*AWSClient).autoscalingconn - gameliftconn := meta.(*AWSClient).gameliftconn - ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig - - gameServerGroupName := d.Id() - - describeGameServerGroupOutput, err := gameliftconn.DescribeGameServerGroup(&gamelift.DescribeGameServerGroupInput{ - GameServerGroupName: aws.String(gameServerGroupName), - }) - - if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, gamelift.ErrCodeNotFoundException) { - log.Printf("[WARN] Gamelift Game Server Group (%s) not found, removing from state", d.Id()) - d.SetId("") - return nil - } - - if err != nil { - return fmt.Errorf("error reading Gamelift Game Server Group (%s): %w", d.Id(), err) - } - - gameServerGroup := describeGameServerGroupOutput.GameServerGroup - - // To view properties of automatically created Auto Scaling group users should access it directly: - // https://docs.aws.amazon.com/gamelift/latest/apireference/API_DescribeGameServerGroup.html - autoScalingGroupName := strings.Split(aws.StringValue(gameServerGroup.AutoScalingGroupArn), "/")[1] - autoScalingGroup, err := getAwsAutoscalingGroup(autoScalingGroupName, autoscalingconn) - - if err != nil { - return err - } - - if autoScalingGroup == nil { - return fmt.Errorf("error describing Auto Scaling Group (%s): not found", autoScalingGroupName) - } - - describePoliciesOutput, err := autoscalingconn.DescribePolicies(&autoscaling.DescribePoliciesInput{ - AutoScalingGroupName: aws.String(autoScalingGroupName), - PolicyNames: []*string{aws.String(gameServerGroupName)}, - }) - - if err != nil { - return fmt.Errorf("error describing Auto Scaling Group Policies (%s): %s", autoScalingGroupName, err) - } - - arn := aws.StringValue(gameServerGroup.GameServerGroupArn) - d.Set("arn", arn) - d.Set("auto_scaling_group_arn", gameServerGroup.AutoScalingGroupArn) - d.Set("balancing_strategy", gameServerGroup.BalancingStrategy) - d.Set("game_server_group_name", gameServerGroupName) - d.Set("game_server_protection_policy", gameServerGroup.GameServerProtectionPolicy) - d.Set("max_size", autoScalingGroup.MaxSize) - d.Set("min_size", autoScalingGroup.MinSize) - d.Set("role_arn", gameServerGroup.RoleArn) - - // d.Set("vpc_subnets", ...) is absent because Gamelift doesn't return its value in API - // and dynamically changes autoScalingGroup.VPCZoneIdentifier using its proprietary FleetIQ Spot Viability algorithm. - - if len(describePoliciesOutput.ScalingPolicies) == 1 { - if err := d.Set("auto_scaling_policy", []interface{}{flattenGameliftGameServerGroupAutoScalingPolicy(describePoliciesOutput.ScalingPolicies[0])}); err != nil { - return fmt.Errorf("error setting auto_scaling_policy: %w", err) - } - } else { - d.Set("auto_scaling_policy", nil) - } - - if err := d.Set("instance_definition", flattenGameliftInstanceDefinitions(gameServerGroup.InstanceDefinitions)); err != nil { - return fmt.Errorf("error setting instance_definition: %s", err) - } - - if err := d.Set("launch_template", flattenLaunchTemplateSpecification(autoScalingGroup.MixedInstancesPolicy.LaunchTemplate.LaunchTemplateSpecification)); err != nil { - return fmt.Errorf("error setting launch_template: %s", err) - } - - tags, err := keyvaluetags.GameliftListTags(gameliftconn, arn) - - if err != nil { - return fmt.Errorf("error listing tags for Game Lift Game Server Group (%s): %s", arn, err) - } - - if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %s", err) - } - - return nil -} - -func resourceAwsGameliftGameServerGroupUpdate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).gameliftconn - - gameServerGroupName := d.Id() - - if d.HasChanges("balancing_strategy", "game_server_protection_policy", "instance_definition", "role_arn") { - input := gamelift.UpdateGameServerGroupInput{ - GameServerGroupName: aws.String(gameServerGroupName), - InstanceDefinitions: expandGameliftInstanceDefinitions(d.Get("instance_definition").(*schema.Set).List()), - RoleArn: aws.String(d.Get("role_arn").(string)), - } - - if v, ok := d.GetOk("balancing_strategy"); ok { - input.BalancingStrategy = aws.String(v.(string)) - } - - if v, ok := d.GetOk("game_server_protection_policy"); ok { - input.GameServerProtectionPolicy = aws.String(v.(string)) - } - - _, err := conn.UpdateGameServerGroup(&input) - - if err != nil { - return fmt.Errorf("error updating GameLift Game Server Group (%s): %w", d.Id(), err) - } - } - - arn := d.Get("arn").(string) - - if d.HasChange("tags") { - o, n := d.GetChange("tags") - - if err := keyvaluetags.GameliftUpdateTags(conn, arn, o, n); err != nil { - return fmt.Errorf("error updating Game Lift Fleet (%s) tags: %s", arn, err) - } - } - - return resourceAwsGameliftGameServerGroupRead(d, meta) -} - -func resourceAwsGameliftGameServerGroupDelete(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).gameliftconn - - gameServerGroupName := d.Id() - - _, err := conn.DeleteGameServerGroup(&gamelift.DeleteGameServerGroupInput{ - GameServerGroupName: aws.String(gameServerGroupName), - }) - - if tfawserr.ErrCodeEquals(err, gamelift.ErrCodeNotFoundException) { - return nil - } - - if err != nil { - return fmt.Errorf("error deleting Gamelift Game Server Group (%s): %w", d.Id(), err) - } - - _, err = waiter.GameServerGroupDeleted(conn, d.Id(), d.Timeout(schema.TimeoutDelete)) - - if tfawserr.ErrCodeEquals(err, gamelift.ErrCodeNotFoundException) { - return nil - } - - if err != nil { - return fmt.Errorf("error waiting for Gamelift Game Server Group (%s) deletion: %w", d.Id(), err) - } - - return nil -} - -func expandGameliftGameServerGroupAutoScalingPolicy(tfMap map[string]interface{}) *gamelift.GameServerGroupAutoScalingPolicy { - if tfMap == nil { - return nil - } - - apiObject := &gamelift.GameServerGroupAutoScalingPolicy{ - TargetTrackingConfiguration: expandGameliftTargetTrackingConfiguration(tfMap["target_tracking_configuration"].([]interface{})[0].(map[string]interface{})), - } - - if v, ok := tfMap["estimated_instance_warmup"].(int); ok && v != 0 { - apiObject.EstimatedInstanceWarmup = aws.Int64(int64(v)) - } - - return apiObject -} - -func expandGameliftInstanceDefinition(tfMap map[string]interface{}) *gamelift.InstanceDefinition { - if tfMap == nil { - return nil - } - - apiObject := &gamelift.InstanceDefinition{ - InstanceType: aws.String(tfMap["instance_type"].(string)), - } - - if v, ok := tfMap["weighted_capacity"].(string); ok && v != "" { - apiObject.WeightedCapacity = aws.String(v) - } - - return apiObject -} - -func expandGameliftInstanceDefinitions(tfList []interface{}) []*gamelift.InstanceDefinition { - if len(tfList) == 0 { - return nil - } - - var apiObjects []*gamelift.InstanceDefinition - - for _, tfMapRaw := range tfList { - tfMap, ok := tfMapRaw.(map[string]interface{}) - - if !ok { - continue - } - - apiObject := expandGameliftInstanceDefinition(tfMap) - - if apiObject == nil { - continue - } - - apiObjects = append(apiObjects, apiObject) - } - - return apiObjects -} - -func expandGameliftLaunchTemplateSpecification(tfMap map[string]interface{}) *gamelift.LaunchTemplateSpecification { - if tfMap == nil { - return nil - } - - apiObject := &gamelift.LaunchTemplateSpecification{} - - if v, ok := tfMap["id"].(string); ok && v != "" { - apiObject.LaunchTemplateId = aws.String(v) - } - - if v, ok := tfMap["name"].(string); ok && v != "" { - apiObject.LaunchTemplateName = aws.String(v) - } - - if v, ok := tfMap["version"].(string); ok && v != "" { - apiObject.Version = aws.String(v) - } - - return apiObject -} - -func expandGameliftTargetTrackingConfiguration(tfMap map[string]interface{}) *gamelift.TargetTrackingConfiguration { - if tfMap == nil { - return nil - } - - apiObject := &gamelift.TargetTrackingConfiguration{ - TargetValue: aws.Float64(tfMap["target_value"].(float64)), - } - - return apiObject -} - -func flattenGameliftGameServerGroupAutoScalingPolicy(apiObject *autoscaling.ScalingPolicy) map[string]interface{} { - if apiObject == nil { - return nil - } - - tfMap := map[string]interface{}{ - "target_tracking_configuration": []interface{}{flattenGameliftTargetTrackingConfiguration(apiObject.TargetTrackingConfiguration)}, - } - - if v := apiObject.EstimatedInstanceWarmup; v != nil { - tfMap["estimated_instance_warmup"] = aws.Int64Value(v) - } - - return tfMap -} - -func flattenGameliftInstanceDefinition(apiObject *gamelift.InstanceDefinition) map[string]interface{} { - if apiObject == nil { - return nil - } - - tfMap := map[string]interface{}{ - "instance_type": aws.StringValue(apiObject.InstanceType), - } - - if v := apiObject.WeightedCapacity; v != nil { - tfMap["weighted_capacity"] = aws.StringValue(v) - } - - return tfMap -} - -func flattenGameliftInstanceDefinitions(apiObjects []*gamelift.InstanceDefinition) []interface{} { - if len(apiObjects) == 0 { - return nil - } - - var tfList []interface{} - - for _, apiObject := range apiObjects { - if apiObject == nil { - continue - } - - tfList = append(tfList, flattenGameliftInstanceDefinition(apiObject)) - } - - return tfList -} - -func flattenGameliftTargetTrackingConfiguration(apiObject *autoscaling.TargetTrackingConfiguration) map[string]interface{} { - if apiObject == nil { - return nil - } - - tfMap := map[string]interface{}{ - "target_value": aws.Float64Value(apiObject.TargetValue), - } - - return tfMap -} diff --git a/aws/resource_aws_gamelift_game_server_group_test.go b/aws/resource_aws_gamelift_game_server_group_test.go deleted file mode 100644 index 6171796f7c4..00000000000 --- a/aws/resource_aws_gamelift_game_server_group_test.go +++ /dev/null @@ -1,1238 +0,0 @@ -package aws - -import ( - "fmt" - "log" - "regexp" - "testing" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/gamelift" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" - "github.com/hashicorp/go-multierror" - "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" -) - -func init() { - resource.AddTestSweepers("aws_gamelift_game_server_group", &resource.Sweeper{ - Name: "aws_gamelift_game_server_group", - F: testSweepGameliftGameServerGroups, - }) -} - -func testSweepGameliftGameServerGroups(region string) error { - client, err := sharedClientForRegion(region) - - if err != nil { - return fmt.Errorf("error getting client: %w", err) - } - - conn := client.(*AWSClient).gameliftconn - input := &gamelift.ListGameServerGroupsInput{} - var sweeperErrs *multierror.Error - - err = conn.ListGameServerGroupsPages(input, func(page *gamelift.ListGameServerGroupsOutput, isLast bool) bool { - if page == nil { - return !isLast - } - - for _, gameServerGroup := range page.GameServerGroups { - id := aws.StringValue(gameServerGroup.GameServerGroupName) - - input := &gamelift.DeleteGameServerGroupInput{ - GameServerGroupName: gameServerGroup.GameServerGroupName, - } - - log.Printf("[INFO] Deleting Gamelift Game Server Group: %s", id) - _, err := conn.DeleteGameServerGroup(input) - - if err != nil { - sweeperErr := fmt.Errorf("error deleting Gamelift Game Server Group (%s): %w", id, err) - log.Printf("[ERROR] %s", sweeperErr) - sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) - continue - } - } - - return !isLast - }) - - if testSweepSkipSweepError(err) { - log.Printf("[WARN] Skipping Gamelift Game Server Group sweep for %s: %s", region, err) - return sweeperErrs.ErrorOrNil() - } - - if err != nil { - sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving Gamelift Game Server Groups: %w", err)) - } - - return sweeperErrs.ErrorOrNil() -} - -func TestAccGameliftGameServerGroup_basic(t *testing.T) { - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_gamelift_game_server_group.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckAWSGamelift(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGameliftGameServerGroupConfig(rName), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - testAccCheckResourceAttrRegionalARN(resourceName, "arn", "gamelift", fmt.Sprintf(`gameservergroup/%s`, rName)), - testAccMatchResourceAttrRegionalARN(resourceName, "auto_scaling_group_arn", "autoscaling", regexp.MustCompile(`autoScalingGroup:.+`)), - resource.TestCheckResourceAttr(resourceName, "auto_scaling_policy.#", "0"), - resource.TestCheckResourceAttr(resourceName, "balancing_strategy", gamelift.BalancingStrategySpotPreferred), - resource.TestCheckResourceAttr(resourceName, "game_server_protection_policy", gamelift.GameServerProtectionPolicyNoProtection), - resource.TestCheckResourceAttr(resourceName, "launch_template.0.version", ""), - resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccGameliftGameServerGroup_AutoScalingPolicy(t *testing.T) { - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_gamelift_game_server_group.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckAWSGamelift(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGameliftGameServerGroupConfigAutoScalingPolicy(rName), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "auto_scaling_policy.0.estimated_instance_warmup", "60"), - resource.TestCheckResourceAttr(resourceName, "auto_scaling_policy.0.target_tracking_configuration.0.target_value", "77.7"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccGameliftGameServerGroup_AutoScalingPolicy_EstimatedInstanceWarmup(t *testing.T) { - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_gamelift_game_server_group.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckAWSGamelift(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGameliftGameServerGroupConfigAutoScalingPolicyEstimatedInstanceWarmup(rName), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "auto_scaling_policy.0.estimated_instance_warmup", "66"), - resource.TestCheckResourceAttr(resourceName, "auto_scaling_policy.0.target_tracking_configuration.0.target_value", "77.7"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccGameliftGameServerGroup_BalancingStrategy(t *testing.T) { - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_gamelift_game_server_group.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckAWSGamelift(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGameliftGameServerGroupConfigBalancingStrategy(rName, gamelift.BalancingStrategySpotOnly), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "balancing_strategy", gamelift.BalancingStrategySpotOnly), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccGameliftGameServerGroup_GameServerGroupName(t *testing.T) { - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_gamelift_game_server_group.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckAWSGamelift(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGameliftGameServerGroupConfigGameServerGroupName(rName, rName), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "game_server_group_name", rName), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccGameliftGameServerGroupConfigGameServerGroupName(rName, rName+"-new"), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "game_server_group_name", rName+"-new"), - ), - }, - }, - }) -} - -func TestAccGameliftGameServerGroup_InstanceDefinition(t *testing.T) { - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_gamelift_game_server_group.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckAWSGamelift(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGameliftGameServerGroupConfigInstanceDefinition(rName, 2), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "instance_definition.#", "2"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccGameliftGameServerGroupConfigInstanceDefinition(rName, 3), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "instance_definition.#", "3"), - ), - }, - }, - }) -} - -func TestAccGameliftGameServerGroup_InstanceDefinition_WeightedCapacity(t *testing.T) { - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_gamelift_game_server_group.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckAWSGamelift(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGameliftGameServerGroupConfigInstanceDefinitionWeightedCapacity(rName, "1"), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "instance_definition.#", "2"), - resource.TestCheckResourceAttr(resourceName, "instance_definition.0.weighted_capacity", "1"), - resource.TestCheckResourceAttr(resourceName, "instance_definition.1.weighted_capacity", "1"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccGameliftGameServerGroupConfigInstanceDefinitionWeightedCapacity(rName, "2"), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "instance_definition.#", "2"), - resource.TestCheckResourceAttr(resourceName, "instance_definition.0.weighted_capacity", "2"), - resource.TestCheckResourceAttr(resourceName, "instance_definition.1.weighted_capacity", "2"), - ), - }, - }, - }) -} - -func TestAccGameliftGameServerGroup_LaunchTemplate_Id(t *testing.T) { - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_gamelift_game_server_group.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckAWSGamelift(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGameliftGameServerGroupConfigLaunchTemplateId(rName), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttrPair(resourceName, "launch_template.0.id", "aws_launch_template.test", "id"), - resource.TestCheckResourceAttr(resourceName, "launch_template.0.name", rName), - resource.TestCheckResourceAttr(resourceName, "launch_template.0.version", ""), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccGameliftGameServerGroup_LaunchTemplate_Name(t *testing.T) { - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_gamelift_game_server_group.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckAWSGamelift(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGameliftGameServerGroupConfigLaunchTemplateName(rName), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttrPair(resourceName, "launch_template.0.id", "aws_launch_template.test", "id"), - resource.TestCheckResourceAttr(resourceName, "launch_template.0.name", rName), - resource.TestCheckResourceAttr(resourceName, "launch_template.0.version", ""), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccGameliftGameServerGroup_LaunchTemplate_Version(t *testing.T) { - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_gamelift_game_server_group.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckAWSGamelift(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGameliftGameServerGroupConfigLaunchTemplateVersion(rName), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttrPair(resourceName, "launch_template.0.id", "aws_launch_template.test", "id"), - resource.TestCheckResourceAttr(resourceName, "launch_template.0.name", rName), - resource.TestCheckResourceAttr(resourceName, "launch_template.0.version", "1"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccGameliftGameServerGroup_GameServerProtectionPolicy(t *testing.T) { - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_gamelift_game_server_group.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckAWSGamelift(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGameliftGameServerGroupConfigGameServerProtectionPolicy(rName, gamelift.GameServerProtectionPolicyFullProtection), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "game_server_protection_policy", gamelift.GameServerProtectionPolicyFullProtection), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - }, - }) -} - -func TestAccGameliftGameServerGroup_MaxSize(t *testing.T) { - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_gamelift_game_server_group.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckAWSGamelift(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGameliftGameServerGroupConfigMaxSize(rName, "1"), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "max_size", "1"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccGameliftGameServerGroupConfigMaxSize(rName, "2"), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "max_size", "2"), - ), - }, - }, - }) -} - -func TestAccGameliftGameServerGroup_MinSize(t *testing.T) { - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_gamelift_game_server_group.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckAWSGamelift(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGameliftGameServerGroupConfigMinSize(rName, "1"), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "min_size", "1"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccGameliftGameServerGroupConfigMinSize(rName, "2"), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "min_size", "2"), - ), - }, - }, - }) -} - -func TestAccGameliftGameServerGroup_RoleArn(t *testing.T) { - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_gamelift_game_server_group.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckAWSGamelift(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGameliftGameServerGroupConfigRoleArn(rName, "test1"), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - testAccCheckResourceAttrGlobalARN(resourceName, "role_arn", "iam", fmt.Sprintf(`role/%s-test1`, rName)), - resource.TestCheckResourceAttrPair(resourceName, "role_arn", "aws_iam_role.test1", "arn"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccGameliftGameServerGroupConfigRoleArn(rName, "test2"), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - testAccCheckResourceAttrGlobalARN(resourceName, "role_arn", "iam", fmt.Sprintf(`role/%s-test2`, rName)), - resource.TestCheckResourceAttrPair(resourceName, "role_arn", "aws_iam_role.test2", "arn"), - ), - }, - }, - }) -} - -func TestAccGameliftGameServerGroup_Tags(t *testing.T) { - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_gamelift_game_server_group.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckAWSGamelift(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGameliftGameServerGroupConfigTags(rName, "key1", "value1"), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), - resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - }, - { - Config: testAccGameliftGameServerGroupConfigTags(rName, "key2", "value2"), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), - resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), - ), - }, - }, - }) -} - -func TestAccGameliftGameServerGroup_VpcSubnets(t *testing.T) { - rName := acctest.RandomWithPrefix("tf-acc-test") - resourceName := "aws_gamelift_game_server_group.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckAWSGamelift(t) - }, - Providers: testAccProviders, - CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: testAccGameliftGameServerGroupConfigVpcSubnets(rName, 1), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"vpc_subnets"}, - }, - { - Config: testAccGameliftGameServerGroupConfigVpcSubnets(rName, 2), - Check: resource.ComposeTestCheckFunc( - testAccCheckGameliftGameServerGroupExists(resourceName), - ), - }, - }, - }) -} - -func testAccCheckGameliftGameServerGroupDestroy(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).gameliftconn - - for _, rs := range s.RootModule().Resources { - if rs.Type != "aws_gamelift_game_server_group" { - continue - } - - input := gamelift.DescribeGameServerGroupInput{ - GameServerGroupName: aws.String(rs.Primary.ID), - } - - output, err := conn.DescribeGameServerGroup(&input) - - if tfawserr.ErrCodeEquals(err, gamelift.ErrCodeNotFoundException) { - continue - } - - if err != nil { - return err - } - - if output != nil { - return fmt.Errorf("Gamelift Game Server Group (%s) still exists", rs.Primary.ID) - } - } - - return nil -} - -func testAccCheckGameliftGameServerGroupExists(resourceName string) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[resourceName] - - if !ok { - return fmt.Errorf("resource %s not found", resourceName) - } - - if rs.Primary.ID == "" { - return fmt.Errorf("resource %s has not set its id", resourceName) - } - - conn := testAccProvider.Meta().(*AWSClient).gameliftconn - - input := gamelift.DescribeGameServerGroupInput{ - GameServerGroupName: aws.String(rs.Primary.ID), - } - - output, err := conn.DescribeGameServerGroup(&input) - - if err != nil { - return fmt.Errorf("error reading Gamelift Game Server Group (%s): %w", rs.Primary.ID, err) - } - - if output == nil { - return fmt.Errorf("Gamelift Game Server Group (%s) not found", rs.Primary.ID) - } - - return nil - } -} - -func testAccGameliftGameServerGroupIamConfig(rName string, name string) string { - return fmt.Sprintf(` -data "aws_partition" "current" {} - -resource "aws_iam_role" %[2]q { - assume_role_policy = <<-EOF - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Principal": { - "Service": [ - "autoscaling.amazonaws.com", - "gamelift.amazonaws.com" - ] - }, - "Action": "sts:AssumeRole" - } - ] - } - EOF - - name = "%[1]s-%[2]s" -} - -resource "aws_iam_role_policy_attachment" %[2]q { - policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/GameLiftGameServerGroupPolicy" - role = aws_iam_role.%[2]s.name -} -`, rName, name) -} - -func testAccGameliftGameServerGroupLaunchTemplateConfig(rName string) string { - return fmt.Sprintf(` -resource "aws_launch_template" "test" { - image_id = data.aws_ami.amzn-ami-minimal-hvm-ebs.id - name = %[1]q -} -`, rName) -} - -func testAccGameliftGameServerGroupInstanceTypeOfferingsConfig() string { - return ` -data "aws_ec2_instance_type_offerings" "available" { - filter { - name = "instance-type" - values = ["c5a.large", "c5a.2xlarge", "c5.large", "c5.2xlarge", "m4.large", "m4.2xlarge", "m5a.large", "m5a.2xlarge", "m5.large", "m5.2xlarge"] - } -} -` -} - -func testAccGameliftGameServerGroupConfig(rName string) string { - return composeConfig( - testAccLatestAmazonLinuxHvmEbsAmiConfig(), - testAccGameliftGameServerGroupIamConfig(rName, "test"), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -resource "aws_gamelift_game_server_group" "test" { - game_server_group_name = %[1]q - - dynamic "instance_definition" { - for_each = data.aws_ec2_instance_type_offerings.available.instance_types - - content { - instance_type = instance_definition.key - } - } - - launch_template { - id = aws_launch_template.test.id - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.test.arn - - depends_on = [aws_iam_role_policy_attachment.test] -} -`, rName)) -} - -func testAccGameliftGameServerGroupConfigAutoScalingPolicy(rName string) string { - return composeConfig( - testAccLatestAmazonLinuxHvmEbsAmiConfig(), - testAccGameliftGameServerGroupIamConfig(rName, "test"), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -resource "aws_gamelift_game_server_group" "test" { - auto_scaling_policy { - target_tracking_configuration { - target_value = 77.7 - } - } - - game_server_group_name = %[1]q - - dynamic "instance_definition" { - for_each = data.aws_ec2_instance_type_offerings.available.instance_types - - content { - instance_type = instance_definition.key - } - } - - launch_template { - id = aws_launch_template.test.id - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.test.arn - - depends_on = [aws_iam_role_policy_attachment.test] -} -`, rName)) -} - -func testAccGameliftGameServerGroupConfigAutoScalingPolicyEstimatedInstanceWarmup(rName string) string { - return composeConfig( - testAccLatestAmazonLinuxHvmEbsAmiConfig(), - testAccGameliftGameServerGroupIamConfig(rName, "test"), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -resource "aws_gamelift_game_server_group" "test" { - auto_scaling_policy { - estimated_instance_warmup = 66 - - target_tracking_configuration { - target_value = 77.7 - } - } - - game_server_group_name = %[1]q - - dynamic "instance_definition" { - for_each = data.aws_ec2_instance_type_offerings.available.instance_types - - content { - instance_type = instance_definition.key - } - } - - launch_template { - id = aws_launch_template.test.id - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.test.arn - - depends_on = [aws_iam_role_policy_attachment.test] -} -`, rName)) -} - -func testAccGameliftGameServerGroupConfigBalancingStrategy(rName string, balancingStrategy string) string { - return composeConfig( - testAccLatestAmazonLinuxHvmEbsAmiConfig(), - testAccGameliftGameServerGroupIamConfig(rName, "test"), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -resource "aws_gamelift_game_server_group" "test" { - balancing_strategy = %[2]q - game_server_group_name = %[1]q - - dynamic "instance_definition" { - for_each = data.aws_ec2_instance_type_offerings.available.instance_types - - content { - instance_type = instance_definition.key - } - } - - launch_template { - id = aws_launch_template.test.id - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.test.arn - - depends_on = [aws_iam_role_policy_attachment.test] -} -`, rName, balancingStrategy)) -} - -func testAccGameliftGameServerGroupConfigGameServerGroupName(rName string, gameServerGroupName string) string { - return composeConfig( - testAccLatestAmazonLinuxHvmEbsAmiConfig(), - testAccGameliftGameServerGroupIamConfig(rName, "test"), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -resource "aws_gamelift_game_server_group" "test" { - game_server_group_name = %[1]q - - dynamic "instance_definition" { - for_each = data.aws_ec2_instance_type_offerings.available.instance_types - - content { - instance_type = instance_definition.key - } - } - - launch_template { - id = aws_launch_template.test.id - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.test.arn - - depends_on = [aws_iam_role_policy_attachment.test] -} -`, gameServerGroupName)) -} - -func testAccGameliftGameServerGroupConfigInstanceDefinition(rName string, count int) string { - return composeConfig( - testAccLatestAmazonLinuxHvmEbsAmiConfig(), - testAccGameliftGameServerGroupIamConfig(rName, "test"), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -resource "aws_gamelift_game_server_group" "test" { - game_server_group_name = %[1]q - - dynamic "instance_definition" { - for_each = slice(tolist(data.aws_ec2_instance_type_offerings.available.instance_types), 0, %[2]d) - - content { - instance_type = instance_definition.value - } - } - - launch_template { - id = aws_launch_template.test.id - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.test.arn - - depends_on = [aws_iam_role_policy_attachment.test] -} -`, rName, count)) -} - -func testAccGameliftGameServerGroupConfigInstanceDefinitionWeightedCapacity(rName string, weightedCapacity string) string { - return composeConfig( - testAccLatestAmazonLinuxHvmEbsAmiConfig(), - testAccGameliftGameServerGroupIamConfig(rName, "test"), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -resource "aws_gamelift_game_server_group" "test" { - game_server_group_name = %[1]q - - dynamic "instance_definition" { - for_each = slice(tolist(data.aws_ec2_instance_type_offerings.available.instance_types), 0, 2) - - content { - instance_type = instance_definition.value - weighted_capacity = %[2]q - } - } - - launch_template { - id = aws_launch_template.test.id - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.test.arn - - depends_on = [aws_iam_role_policy_attachment.test] -} -`, rName, weightedCapacity)) -} -func testAccGameliftGameServerGroupConfigLaunchTemplateId(rName string) string { - return composeConfig( - testAccLatestAmazonLinuxHvmEbsAmiConfig(), - testAccGameliftGameServerGroupIamConfig(rName, "test"), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -resource "aws_gamelift_game_server_group" "test" { - game_server_group_name = %[1]q - - dynamic "instance_definition" { - for_each = data.aws_ec2_instance_type_offerings.available.instance_types - - content { - instance_type = instance_definition.key - } - } - - launch_template { - id = aws_launch_template.test.id - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.test.arn - - depends_on = [aws_iam_role_policy_attachment.test] -} -`, rName)) -} - -func testAccGameliftGameServerGroupConfigLaunchTemplateName(rName string) string { - return composeConfig( - testAccLatestAmazonLinuxHvmEbsAmiConfig(), - testAccGameliftGameServerGroupIamConfig(rName, "test"), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -resource "aws_gamelift_game_server_group" "test" { - game_server_group_name = %[1]q - - dynamic "instance_definition" { - for_each = data.aws_ec2_instance_type_offerings.available.instance_types - - content { - instance_type = instance_definition.key - } - } - - launch_template { - name = aws_launch_template.test.name - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.test.arn - - depends_on = [aws_iam_role_policy_attachment.test] -} -`, rName)) -} - -func testAccGameliftGameServerGroupConfigLaunchTemplateVersion(rName string) string { - return composeConfig( - testAccLatestAmazonLinuxHvmEbsAmiConfig(), - testAccGameliftGameServerGroupIamConfig(rName, "test"), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -resource "aws_gamelift_game_server_group" "test" { - game_server_group_name = %[1]q - - dynamic "instance_definition" { - for_each = data.aws_ec2_instance_type_offerings.available.instance_types - - content { - instance_type = instance_definition.key - } - } - - launch_template { - id = aws_launch_template.test.id - version = 1 - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.test.arn - - depends_on = [aws_iam_role_policy_attachment.test] -} -`, rName)) -} - -func testAccGameliftGameServerGroupConfigMaxSize(rName string, maxSize string) string { - return composeConfig( - testAccLatestAmazonLinuxHvmEbsAmiConfig(), - testAccGameliftGameServerGroupIamConfig(rName, "test"), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -resource "aws_gamelift_game_server_group" "test" { - game_server_group_name = %[1]q - - dynamic "instance_definition" { - for_each = data.aws_ec2_instance_type_offerings.available.instance_types - - content { - instance_type = instance_definition.key - } - } - - launch_template { - id = aws_launch_template.test.id - } - - max_size = %[2]s - min_size = 1 - role_arn = aws_iam_role.test.arn - - depends_on = [aws_iam_role_policy_attachment.test] -} -`, rName, maxSize)) -} - -func testAccGameliftGameServerGroupConfigMinSize(rName string, minSize string) string { - return composeConfig( - testAccLatestAmazonLinuxHvmEbsAmiConfig(), - testAccGameliftGameServerGroupIamConfig(rName, "test"), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -resource "aws_gamelift_game_server_group" "test" { - game_server_group_name = %[1]q - - dynamic "instance_definition" { - for_each = data.aws_ec2_instance_type_offerings.available.instance_types - - content { - instance_type = instance_definition.key - } - } - - launch_template { - id = aws_launch_template.test.id - } - - max_size = 2 - min_size = %[2]s - role_arn = aws_iam_role.test.arn - - depends_on = [aws_iam_role_policy_attachment.test] -} -`, rName, minSize)) -} - -func testAccGameliftGameServerGroupConfigTags(rName string, key string, value string) string { - return composeConfig( - testAccLatestAmazonLinuxHvmEbsAmiConfig(), - testAccGameliftGameServerGroupIamConfig(rName, "test"), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -resource "aws_gamelift_game_server_group" "test" { - game_server_group_name = %[1]q - - dynamic "instance_definition" { - for_each = data.aws_ec2_instance_type_offerings.available.instance_types - - content { - instance_type = instance_definition.key - } - } - - launch_template { - id = aws_launch_template.test.id - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.test.arn - - tags = { - %[2]s = %[3]q - } - - depends_on = [aws_iam_role_policy_attachment.test] -} -`, rName, key, value)) -} - -func testAccGameliftGameServerGroupConfigGameServerProtectionPolicy(rName string, gameServerProtectionPolicy string) string { - return composeConfig( - testAccLatestAmazonLinuxHvmEbsAmiConfig(), - testAccGameliftGameServerGroupIamConfig(rName, "test"), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -resource "aws_gamelift_game_server_group" "test" { - game_server_group_name = %[1]q - game_server_protection_policy = %[2]q - - dynamic "instance_definition" { - for_each = data.aws_ec2_instance_type_offerings.available.instance_types - - content { - instance_type = instance_definition.key - } - } - - launch_template { - id = aws_launch_template.test.id - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.test.arn - - depends_on = [aws_iam_role_policy_attachment.test] -} -`, rName, gameServerProtectionPolicy)) -} - -func testAccGameliftGameServerGroupConfigRoleArn(rName string, roleArn string) string { - return composeConfig( - testAccLatestAmazonLinuxHvmEbsAmiConfig(), - testAccGameliftGameServerGroupIamConfig(rName, roleArn), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -resource "aws_gamelift_game_server_group" "test" { - game_server_group_name = %[1]q - - dynamic "instance_definition" { - for_each = data.aws_ec2_instance_type_offerings.available.instance_types - - content { - instance_type = instance_definition.key - } - } - - launch_template { - id = aws_launch_template.test.id - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.%[2]s.arn - - depends_on = [aws_iam_role_policy_attachment.%[2]s] -} -`, rName, roleArn)) -} - -func testAccGameliftGameServerGroupConfigVpcSubnets(rName string, count int) string { - return composeConfig( - testAccLatestAmazonLinuxHvmEbsAmiConfig(), - testAccGameliftGameServerGroupIamConfig(rName, "test"), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -data "aws_vpc" "test" { - default = true -} - -data "aws_subnet_ids" "test" { - vpc_id = data.aws_vpc.test.id -} - -resource "aws_gamelift_game_server_group" "test" { - game_server_group_name = %[1]q - - dynamic "instance_definition" { - for_each = data.aws_ec2_instance_type_offerings.available.instance_types - - content { - instance_type = instance_definition.key - } - } - - launch_template { - id = aws_launch_template.test.id - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.test.arn - vpc_subnets = slice(tolist(data.aws_subnet_ids.test.ids), 0, %[2]d) - - depends_on = [aws_iam_role_policy_attachment.test] -} -`, rName, count)) -} diff --git a/website/docs/r/gamelift_game_server_group.html.markdown b/website/docs/r/gamelift_game_server_group.html.markdown deleted file mode 100644 index b72a9d42ac8..00000000000 --- a/website/docs/r/gamelift_game_server_group.html.markdown +++ /dev/null @@ -1,206 +0,0 @@ ---- -subcategory: "Gamelift" -layout: "aws" -page_title: "AWS: aws_gamelift_game_server_group" -description: |- -Provides a Gamelift Game Server Group resource. ---- - -# Resource: aws_gamelift_game_server_group - -Provides an Gamelift Game Server Group resource. - -## Example Usage - -Basic usage: - -```hcl -resource "aws_gamelift_game_server_group" "example" { - game_server_group_name = "example" - - instance_definition { - instance_type = "c5.large" - } - - instance_definition { - instance_type = "c5a.large" - } - - launch_template { - id = aws_launch_template.example.id - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.example.arn - - depends_on = [ - aws_iam_role_policy_attachment.example - ] -} -``` - -Full usage: - -```hcl -resource "aws_gamelift_game_server_group" "example" { - auto_scaling_policy { - estimated_instance_warmup = 60 - - target_tracking_configuration { - target_value = 75 - } - } - - balancing_strategy = "SPOT_ONLY" - game_server_group_name = "example" - game_server_protection_policy = "FULL_PROTECTION" - - instance_definition { - instance_type = "c5.large" - weighted_capacity = "1" - } - - instance_definition { - instance_type = "c5.2xlarge" - weighted_capacity = "2" - } - - launch_template { - id = aws_launch_template.example.id - version = "1" - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.example.arn - - tags = { - Name = "example" - } - - vpc_subnets = [ - "subnet-12345678", - "subnet-23456789" - ] - - depends_on = [ - aws_iam_role_policy_attachment.example - ] -} -``` - -### Example IAM Role for Gamelift Game Server Group -```hcl -data "aws_partition" "current" {} - -resource "aws_iam_role" "example" { - assume_role_policy = <<-EOF - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Principal": { - "Service": [ - "autoscaling.amazonaws.com", - "gamelift.amazonaws.com" - ] - }, - "Action": "sts:AssumeRole" - } - ] - } - EOF - - name = "gamelift-game-server-group-example" -} - -resource "aws_iam_role_policy_attachment" "example" { - policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/GameLiftGameServerGroupPolicy" - role = aws_iam_role.example.name -} -``` - -## Argument Reference - -The following arguments are supported: - -* `balancing_strategy` - (Optional) Indicates how GameLift FleetIQ balances the use of Spot Instances and On-Demand Instances. - Valid values: `SPOT_ONLY`, `SPOT_PREFERRED`, `ON_DEMAND_ONLY`. Defaults to `SPOT_PREFERRED`. -* `game_server_group_name` - (Required) Name of the game server group. - This value is used to generate unique ARN identifiers for the EC2 Auto Scaling group and the GameLift FleetIQ game server group. -* `game_server_protection_policy` - (Optional) Indicates whether instances in the game server group are protected from early termination. - Unprotected instances that have active game servers running might be terminated during a scale-down event, - causing players to be dropped from the game. - Protected instances cannot be terminated while there are active game servers running except in the event - of a forced game server group deletion. - Valid values: `NO_PROTECTION`, `FULL_PROTECTION`. Defaults to `NO_PROTECTION`. -* `max_size` - (Required) The maximum number of instances allowed in the EC2 Auto Scaling group. - During automatic scaling events, GameLift FleetIQ and EC2 do not scale up the group above this maximum. -* `min_size` - (Required) The minimum number of instances allowed in the EC2 Auto Scaling group. - During automatic scaling events, GameLift FleetIQ and EC2 do not scale down the group below this minimum. -* `role_arn` - (Required) ARN for an IAM role that allows Amazon GameLift to access your EC2 Auto Scaling groups. -* `tags` - (Optional) Key-value map of resource tags -* `vpc_subnets` - (Optional) A list of VPC subnets to use with instances in the game server group. - By default, all GameLift FleetIQ-supported Availability Zones are used. - -### `auto_scaling_policy` -Configuration settings to define a scaling policy for the Auto Scaling group that is optimized for game hosting. -The scaling policy uses the metric `PercentUtilizedGameServers` to maintain a buffer of idle game servers that -can immediately accommodate new games and players. - -* `estimated_instance_warmup` - (Optional) Length of time, in seconds, it takes for a new instance to start - new game server processes and register with GameLift FleetIQ. - Specifying a warm-up time can be useful, particularly with game servers that take a long time to start up, - because it avoids prematurely starting new instances. Defaults to `60`. - -#### `target_tracking_configuration` -Settings for a target-based scaling policy applied to Auto Scaling group. -These settings are used to create a target-based policy that tracks the GameLift FleetIQ metric `PercentUtilizedGameServers` -and specifies a target value for the metric. - -* `target_value` - (Required) Desired value to use with a game server group target-based scaling policy. - -### `instance_definition` -The EC2 instance types and sizes to use in the Auto Scaling group. -The instance definitions must specify at least two different instance types that are supported by GameLift FleetIQ. - -* `instance_type` - (Required) An EC2 instance type. -* `weighted_capacity` - (Optional) Instance weighting that indicates how much this instance type contributes - to the total capacity of a game server group. - Instance weights are used by GameLift FleetIQ to calculate the instance type's cost per unit hour and better identify - the most cost-effective options. - -### `launch_template` -The EC2 launch template that contains configuration settings and game server code to be deployed to all instances in the game server group. -You can specify the template using either the template name or ID. - -* `id` - (Optional) A unique identifier for an existing EC2 launch template. -* `name` - (Optional) A readable identifier for an existing EC2 launch template. -* `version` - (Optional) The version of the EC2 launch template to use. If none is set, the default is the first version created. - -## Attributes Reference - -In addition to all arguments above, the following attributes are exported: - -* `id` - The name of the Gamelift Game Server Group. -* `arn` - The ARN of the Gamelift Game Server Group. -* `auto_scaling_group_arn` - The ARN of the created EC2 Auto Scaling group. - - -## Timeouts - -`aws_gamelift_game_server_group` provides the following -[Timeouts](https://www.terraform.io/docs/configuration/blocks/resources/syntax.html#operation-timeouts) configuration options: - -* `create` - (Default `10 minutes`) How long to wait for the Gamelift Game Server Group to be created. -* `delete` - (Default `30 minutes`) How long to wait for the Gamelift Game Server Group to be deleted. - -## Import - -Gamelift Game Server Group can be imported using the `name`, e.g. - -``` -$ terraform import aws_gamelift_game_server_group.example example -``` From 2c0c4c3d7eff6fcb3ea5cc40534e087cfd311852 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 08:29:39 -0400 Subject: [PATCH 169/229] Fix terrafmt errors in acceptance test configurations. --- .../gamelift/game_server_group_test.go | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/internal/service/gamelift/game_server_group_test.go b/internal/service/gamelift/game_server_group_test.go index 4d033eec97d..c8a585b91d8 100644 --- a/internal/service/gamelift/game_server_group_test.go +++ b/internal/service/gamelift/game_server_group_test.go @@ -583,6 +583,7 @@ func testAccCheckGameliftGameServerGroupExists(resourceName string) resource.Tes func testAccGameliftGameServerGroupIamConfig(rName string, name string) string { return fmt.Sprintf(` data "aws_partition" %[2]q {} + resource "aws_iam_role" %[2]q { assume_role_policy = <<-EOF { @@ -603,9 +604,10 @@ resource "aws_iam_role" %[2]q { EOF name = "%[1]s-%[2]s" } + resource "aws_iam_role_policy_attachment" %[2]q { policy_arn = "arn:${data.aws_partition.%[2]s.partition}:iam::aws:policy/GameLiftGameServerGroupPolicy" - role = aws_iam_role.%[2]s.name + role = aws_iam_role.%[2]s.name } `, rName, name) } @@ -648,9 +650,11 @@ resource "aws_gamelift_game_server_group" "test" { launch_template { id = aws_launch_template.test.id } + max_size = 1 min_size = 1 role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] } `, rName)) @@ -679,9 +683,11 @@ resource "aws_gamelift_game_server_group" "test" { launch_template { id = aws_launch_template.test.id } + max_size = 1 min_size = 1 role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] } `, rName)) @@ -711,9 +717,11 @@ resource "aws_gamelift_game_server_group" "test" { launch_template { id = aws_launch_template.test.id } + max_size = 1 min_size = 1 role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] } `, rName)) @@ -738,9 +746,11 @@ resource "aws_gamelift_game_server_group" "test" { launch_template { id = aws_launch_template.test.id } + max_size = 1 min_size = 1 role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] } `, rName, balancingStrategy)) @@ -764,9 +774,11 @@ resource "aws_gamelift_game_server_group" "test" { launch_template { id = aws_launch_template.test.id } + max_size = 1 min_size = 1 role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] } `, gameServerGroupName)) @@ -790,9 +802,11 @@ resource "aws_gamelift_game_server_group" "test" { launch_template { id = aws_launch_template.test.id } + max_size = 1 min_size = 1 role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] } `, rName, count)) @@ -817,9 +831,11 @@ resource "aws_gamelift_game_server_group" "test" { launch_template { id = aws_launch_template.test.id } + max_size = 1 min_size = 1 role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] } `, rName, weightedCapacity)) @@ -843,9 +859,11 @@ resource "aws_gamelift_game_server_group" "test" { launch_template { id = aws_launch_template.test.id } + max_size = 1 min_size = 1 role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] } `, rName)) @@ -869,9 +887,11 @@ resource "aws_gamelift_game_server_group" "test" { launch_template { name = aws_launch_template.test.name } + max_size = 1 min_size = 1 role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] } `, rName)) @@ -896,9 +916,11 @@ resource "aws_gamelift_game_server_group" "test" { id = aws_launch_template.test.id version = 1 } + max_size = 1 min_size = 1 role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] } `, rName)) @@ -922,9 +944,11 @@ resource "aws_gamelift_game_server_group" "test" { launch_template { id = aws_launch_template.test.id } + max_size = %[2]s min_size = 1 role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] } `, rName, maxSize)) @@ -948,9 +972,11 @@ resource "aws_gamelift_game_server_group" "test" { launch_template { id = aws_launch_template.test.id } + max_size = 2 min_size = %[2]s role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] } `, rName, minSize)) @@ -974,12 +1000,15 @@ resource "aws_gamelift_game_server_group" "test" { launch_template { id = aws_launch_template.test.id } + max_size = 1 min_size = 1 role_arn = aws_iam_role.test.arn + tags = { %[2]s = %[3]q } + depends_on = [aws_iam_role_policy_attachment.test] } `, rName, key, value)) @@ -1004,9 +1033,11 @@ resource "aws_gamelift_game_server_group" "test" { launch_template { id = aws_launch_template.test.id } + max_size = 1 min_size = 1 role_arn = aws_iam_role.test.arn + depends_on = [aws_iam_role_policy_attachment.test] } `, rName, gameServerProtectionPolicy)) @@ -1030,9 +1061,11 @@ resource "aws_gamelift_game_server_group" "test" { launch_template { id = aws_launch_template.test.id } + max_size = 1 min_size = 1 role_arn = aws_iam_role.%[2]s.arn + depends_on = [aws_iam_role_policy_attachment.%[2]s] } `, rName, roleArn)) @@ -1048,9 +1081,11 @@ func testAccGameliftGameServerGroupConfigVpcSubnets(rName string, count int) str data "aws_vpc" "test" { default = true } + data "aws_subnet_ids" "test" { vpc_id = data.aws_vpc.test.id } + resource "aws_gamelift_game_server_group" "test" { game_server_group_name = %[1]q dynamic "instance_definition" { @@ -1062,10 +1097,12 @@ resource "aws_gamelift_game_server_group" "test" { launch_template { id = aws_launch_template.test.id } + max_size = 1 min_size = 1 role_arn = aws_iam_role.test.arn vpc_subnets = slice(tolist(data.aws_subnet_ids.test.ids), 0, %[2]d) + depends_on = [aws_iam_role_policy_attachment.test] } `, rName, count)) From ed07309470ae9e862411ffb0c39580433ef1e2d3 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 08:31:24 -0400 Subject: [PATCH 170/229] Add 'nosemgrep: aws-sdk-go-multiple-service-imports'. --- internal/service/gamelift/game_server_group.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/gamelift/game_server_group.go b/internal/service/gamelift/game_server_group.go index 81edbf9308f..9a44a50e59f 100644 --- a/internal/service/gamelift/game_server_group.go +++ b/internal/service/gamelift/game_server_group.go @@ -1,6 +1,6 @@ package gamelift -import ( +import ( // nosemgrep: aws-sdk-go-multiple-service-imports "fmt" "log" "strings" From 8db835ac6f79714b80ee81dc7153f5f215b54722 Mon Sep 17 00:00:00 2001 From: Roberth Kulbin <6707630+roberth-k@users.noreply.github.com> Date: Sun, 13 Mar 2022 23:26:06 +0000 Subject: [PATCH 171/229] keyspaces: add provider infrastructure --- .github/labeler-issue-triage.yml | 2 ++ .github/labeler-pr-triage.yml | 3 +++ infrastructure/repository/labels-service.tf | 1 + internal/conns/conns.go | 5 +++++ website/allowed-subcategories.txt | 3 ++- website/docs/guides/custom-service-endpoints.html.md | 1 + 6 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/labeler-issue-triage.yml b/.github/labeler-issue-triage.yml index 2cedd00cdcc..83c52d7ea69 100644 --- a/.github/labeler-issue-triage.yml +++ b/.github/labeler-issue-triage.yml @@ -218,6 +218,8 @@ service/kafka: - '((\*|-) ?`?|(data|resource) "?)aws_msk_' service/kafkaconnect: - '((\*|-) ?`?|(data|resource) "?)aws_mskconnect_' +service/keyspaces: + - '((\*|-) ?`?|(data|resource) "?)aws_keyspaces_' service/kinesis: - '((\*|-) ?`?|(data|resource) "?)aws_kinesis_stream' service/kinesisanalytics: diff --git a/.github/labeler-pr-triage.yml b/.github/labeler-pr-triage.yml index c9846bee6b2..8f5d6c19b2e 100644 --- a/.github/labeler-pr-triage.yml +++ b/.github/labeler-pr-triage.yml @@ -376,6 +376,9 @@ service/kafka: service/kafkaconnect: - 'internal/service/kafkaconnect/**/*' - 'website/**/mskconnect_*' +service/keyspaces: + - 'internal/service/keyspaces/**/*' + - 'website/**/keyspaces_*' service/kinesis: - 'internal/service/kinesis/**/*' - '*_aws_kinesis_stream*' diff --git a/infrastructure/repository/labels-service.tf b/infrastructure/repository/labels-service.tf index 5f12bfd0f12..58f273bf9a5 100644 --- a/infrastructure/repository/labels-service.tf +++ b/infrastructure/repository/labels-service.tf @@ -121,6 +121,7 @@ variable "service_labels" { "kafka", "kafkaconnect", "kendra", + "keyspaces", "kinesis", "kinesisanalytics", "kinesisanalyticsv2", diff --git a/internal/conns/conns.go b/internal/conns/conns.go index e0658523a0b..356e90b5341 100644 --- a/internal/conns/conns.go +++ b/internal/conns/conns.go @@ -148,6 +148,7 @@ import ( "github.com/aws/aws-sdk-go/service/kafka" "github.com/aws/aws-sdk-go/service/kafkaconnect" "github.com/aws/aws-sdk-go/service/kendra" + "github.com/aws/aws-sdk-go/service/keyspaces" "github.com/aws/aws-sdk-go/service/kinesis" "github.com/aws/aws-sdk-go/service/kinesisanalytics" "github.com/aws/aws-sdk-go/service/kinesisanalyticsv2" @@ -433,6 +434,7 @@ const ( Kafka = "kafka" KafkaConnect = "kafkaconnect" Kendra = "kendra" + Keyspaces = "keyspaces" Kinesis = "kinesis" KinesisAnalytics = "kinesisanalytics" KinesisAnalyticsV2 = "kinesisanalyticsv2" @@ -729,6 +731,7 @@ func init() { serviceData[Kafka] = &ServiceDatum{AWSClientName: "Kafka", AWSServiceName: kafka.ServiceName, AWSEndpointsID: kafka.EndpointsID, AWSServiceID: kafka.ServiceID, ProviderNameUpper: "Kafka", HCLKeys: []string{"kafka"}} serviceData[KafkaConnect] = &ServiceDatum{AWSClientName: "KafkaConnect", AWSServiceName: kafkaconnect.ServiceName, AWSEndpointsID: kafkaconnect.EndpointsID, AWSServiceID: kafkaconnect.ServiceID, ProviderNameUpper: "KafkaConnect", HCLKeys: []string{"kafkaconnect"}} serviceData[Kendra] = &ServiceDatum{AWSClientName: "Kendra", AWSServiceName: kendra.ServiceName, AWSEndpointsID: kendra.EndpointsID, AWSServiceID: kendra.ServiceID, ProviderNameUpper: "Kendra", HCLKeys: []string{"kendra"}} + serviceData[Keyspaces] = &ServiceDatum{AWSClientName: "Keyspaces", AWSServiceName: keyspaces.ServiceName, AWSEndpointsID: keyspaces.EndpointsID, AWSServiceID: keyspaces.ServiceID, ProviderNameUpper: "Keyspaces", HCLKeys: []string{"keyspaces"}} serviceData[Kinesis] = &ServiceDatum{AWSClientName: "Kinesis", AWSServiceName: kinesis.ServiceName, AWSEndpointsID: kinesis.EndpointsID, AWSServiceID: kinesis.ServiceID, ProviderNameUpper: "Kinesis", HCLKeys: []string{"kinesis"}} serviceData[KinesisAnalytics] = &ServiceDatum{AWSClientName: "KinesisAnalytics", AWSServiceName: kinesisanalytics.ServiceName, AWSEndpointsID: kinesisanalytics.EndpointsID, AWSServiceID: kinesisanalytics.ServiceID, ProviderNameUpper: "KinesisAnalytics", HCLKeys: []string{"kinesisanalytics"}} serviceData[KinesisAnalyticsV2] = &ServiceDatum{AWSClientName: "KinesisAnalyticsV2", AWSServiceName: kinesisanalyticsv2.ServiceName, AWSEndpointsID: kinesisanalyticsv2.EndpointsID, AWSServiceID: kinesisanalyticsv2.ServiceID, ProviderNameUpper: "KinesisAnalyticsV2", HCLKeys: []string{"kinesisanalyticsv2"}} @@ -1040,6 +1043,7 @@ type AWSClient struct { KafkaConn *kafka.Kafka KafkaConnectConn *kafkaconnect.KafkaConnect KendraConn *kendra.Kendra + KeyspacesConn *keyspaces.Keyspaces KinesisAnalyticsConn *kinesisanalytics.KinesisAnalytics KinesisAnalyticsV2Conn *kinesisanalyticsv2.KinesisAnalyticsV2 KinesisConn *kinesis.Kinesis @@ -1438,6 +1442,7 @@ func (c *Config) Client(ctx context.Context) (interface{}, diag.Diagnostics) { KafkaConn: kafka.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[Kafka])})), KafkaConnectConn: kafkaconnect.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[KafkaConnect])})), KendraConn: kendra.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[Kendra])})), + KeyspacesConn: keyspaces.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[Keyspaces])})), KinesisAnalyticsConn: kinesisanalytics.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[KinesisAnalytics])})), KinesisAnalyticsV2Conn: kinesisanalyticsv2.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[KinesisAnalyticsV2])})), KinesisConn: kinesis.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[Kinesis])})), diff --git a/website/allowed-subcategories.txt b/website/allowed-subcategories.txt index a28c1f65fe7..2d6bffb2d45 100644 --- a/website/allowed-subcategories.txt +++ b/website/allowed-subcategories.txt @@ -82,12 +82,13 @@ Identity Store Image Builder Inspector IoT -KMS +Keyspaces Kinesis Kinesis Data Analytics (SQL Applications) Kinesis Data Analytics v2 (SQL and Flink Applications) Kinesis Firehose Kinesis Video +KMS Lake Formation Lambda Lex diff --git a/website/docs/guides/custom-service-endpoints.html.md b/website/docs/guides/custom-service-endpoints.html.md index 7d7e4336c69..b122c9b23b4 100644 --- a/website/docs/guides/custom-service-endpoints.html.md +++ b/website/docs/guides/custom-service-endpoints.html.md @@ -206,6 +206,7 @@ provider "aws" {
  • kafka
  • kafkaconnect
  • kendra
  • +
  • keyspaces
  • kinesis
  • kinesisanalytics
  • kinesisanalyticsv2
  • From aaade49944e8a55e5997fa6e885d433c6d352a8f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 08:47:30 -0400 Subject: [PATCH 172/229] Add CHANGELOG entry. --- .changelog/23535.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/23535.txt diff --git a/.changelog/23535.txt b/.changelog/23535.txt new file mode 100644 index 00000000000..f4d7b48820b --- /dev/null +++ b/.changelog/23535.txt @@ -0,0 +1,3 @@ +```new-data-source +aws_ecrpublic_authorization_token +``` From 8a6187c25b099539a4f241e0b55b7973af33f6e2 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 08:49:01 -0400 Subject: [PATCH 173/229] Add some newlines. --- .../authorization_token_data_source.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/internal/service/ecrpublic/authorization_token_data_source.go b/internal/service/ecrpublic/authorization_token_data_source.go index cfd310a81a9..39399de74f7 100644 --- a/internal/service/ecrpublic/authorization_token_data_source.go +++ b/internal/service/ecrpublic/authorization_token_data_source.go @@ -3,7 +3,6 @@ package ecrpublic import ( "encoding/base64" "fmt" - "log" "strings" "time" @@ -27,15 +26,15 @@ func DataSourceAuthorizationToken() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "user_name": { - Type: schema.TypeString, - Computed: true, - }, "password": { Type: schema.TypeString, Computed: true, Sensitive: true, }, + "user_name": { + Type: schema.TypeString, + Computed: true, + }, }, } } @@ -43,24 +42,26 @@ func DataSourceAuthorizationToken() *schema.Resource { func dataSourceAuthorizationTokenRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).ECRPublicConn params := &ecrpublic.GetAuthorizationTokenInput{} - log.Printf("[DEBUG] Getting Public ECR authorization token") + out, err := conn.GetAuthorizationToken(params) + if err != nil { return fmt.Errorf("error getting Public ECR authorization token: %w", err) } - log.Printf("[DEBUG] Received Public ECR AuthorizationData %v", out.AuthorizationData) + authorizationData := out.AuthorizationData authorizationToken := aws.StringValue(authorizationData.AuthorizationToken) expiresAt := aws.TimeValue(authorizationData.ExpiresAt).Format(time.RFC3339) authBytes, err := base64.URLEncoding.DecodeString(authorizationToken) if err != nil { - d.SetId("") return fmt.Errorf("error decoding Public ECR authorization token: %w", err) } + basicAuthorization := strings.Split(string(authBytes), ":") if len(basicAuthorization) != 2 { return fmt.Errorf("unknown Public ECR authorization token format") } + userName := basicAuthorization[0] password := basicAuthorization[1] d.SetId(meta.(*conns.AWSClient).Region) @@ -68,5 +69,6 @@ func dataSourceAuthorizationTokenRead(d *schema.ResourceData, meta interface{}) d.Set("expires_at", expiresAt) d.Set("user_name", userName) d.Set("password", password) + return nil } From 9c55515eeeab6efb99984d7e32a7d0621aaaabee Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 08:52:55 -0400 Subject: [PATCH 174/229] Fix providerlint 'XAT001: missing ErrorCheck' errors. --- .../service/gamelift/game_server_group_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/internal/service/gamelift/game_server_group_test.go b/internal/service/gamelift/game_server_group_test.go index c8a585b91d8..b5c9a2f8ba0 100644 --- a/internal/service/gamelift/game_server_group_test.go +++ b/internal/service/gamelift/game_server_group_test.go @@ -61,6 +61,7 @@ func TestAccGameliftGameServerGroup_AutoScalingPolicy(t *testing.T) { acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) testAccPreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, gamelift.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, Steps: []resource.TestStep{ @@ -91,6 +92,7 @@ func TestAccGameliftGameServerGroup_AutoScalingPolicy_EstimatedInstanceWarmup(t acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) testAccPreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, gamelift.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, Steps: []resource.TestStep{ @@ -121,6 +123,7 @@ func TestAccGameliftGameServerGroup_BalancingStrategy(t *testing.T) { acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) testAccPreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, gamelift.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, Steps: []resource.TestStep{ @@ -150,6 +153,7 @@ func TestAccGameliftGameServerGroup_GameServerGroupName(t *testing.T) { acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) testAccPreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, gamelift.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, Steps: []resource.TestStep{ @@ -186,6 +190,7 @@ func TestAccGameliftGameServerGroup_InstanceDefinition(t *testing.T) { acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) testAccPreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, gamelift.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, Steps: []resource.TestStep{ @@ -222,6 +227,7 @@ func TestAccGameliftGameServerGroup_InstanceDefinition_WeightedCapacity(t *testi acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) testAccPreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, gamelift.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, Steps: []resource.TestStep{ @@ -262,6 +268,7 @@ func TestAccGameliftGameServerGroup_LaunchTemplate_Id(t *testing.T) { acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) testAccPreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, gamelift.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, Steps: []resource.TestStep{ @@ -293,6 +300,7 @@ func TestAccGameliftGameServerGroup_LaunchTemplate_Name(t *testing.T) { acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) testAccPreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, gamelift.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, Steps: []resource.TestStep{ @@ -324,6 +332,7 @@ func TestAccGameliftGameServerGroup_LaunchTemplate_Version(t *testing.T) { acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) testAccPreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, gamelift.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, Steps: []resource.TestStep{ @@ -355,6 +364,7 @@ func TestAccGameliftGameServerGroup_GameServerProtectionPolicy(t *testing.T) { acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) testAccPreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, gamelift.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, Steps: []resource.TestStep{ @@ -384,6 +394,7 @@ func TestAccGameliftGameServerGroup_MaxSize(t *testing.T) { acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) testAccPreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, gamelift.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, Steps: []resource.TestStep{ @@ -420,6 +431,7 @@ func TestAccGameliftGameServerGroup_MinSize(t *testing.T) { acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) testAccPreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, gamelift.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, Steps: []resource.TestStep{ @@ -456,6 +468,7 @@ func TestAccGameliftGameServerGroup_RoleArn(t *testing.T) { acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) testAccPreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, gamelift.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, Steps: []resource.TestStep{ @@ -494,6 +507,7 @@ func TestAccGameliftGameServerGroup_VpcSubnets(t *testing.T) { acctest.PreCheckPartitionHasService(gamelift.EndpointsID, t) testAccPreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, gamelift.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckGameliftGameServerGroupDestroy, Steps: []resource.TestStep{ From e7bb8515799a614661db43ec0ed4ea783efd2775 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 09:06:03 -0400 Subject: [PATCH 175/229] d/aws_ecrpublic_authorization_token: Additional PreCheck. --- .../service/ecrpublic/authorization_token_data_source_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/ecrpublic/authorization_token_data_source_test.go b/internal/service/ecrpublic/authorization_token_data_source_test.go index 444fe31ef08..41cad8fd6b2 100644 --- a/internal/service/ecrpublic/authorization_token_data_source_test.go +++ b/internal/service/ecrpublic/authorization_token_data_source_test.go @@ -13,7 +13,7 @@ func TestAccECRPublicAuthorizationTokenDataSource_basic(t *testing.T) { dataSourceName := "data.aws_ecrpublic_authorization_token.repo" resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, ecr.EndpointsID), Providers: acctest.Providers, Steps: []resource.TestStep{ From d98baba852640cf354f1b73d91cce1d8b2b8f708 Mon Sep 17 00:00:00 2001 From: zachfeld Date: Wed, 9 Mar 2022 16:39:30 -0500 Subject: [PATCH 176/229] r/aws_ecs_service: remove ForceNew from resource arguments --- internal/service/ecs/service.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/internal/service/ecs/service.go b/internal/service/ecs/service.go index 674fd98771f..6bb0d437189 100644 --- a/internal/service/ecs/service.go +++ b/internal/service/ecs/service.go @@ -153,7 +153,6 @@ func ResourceService() *schema.Resource { Type: schema.TypeBool, Optional: true, Default: false, - ForceNew: true, }, "enable_execute_command": { Type: schema.TypeBool, @@ -185,7 +184,6 @@ func ResourceService() *schema.Resource { "load_balancer": { Type: schema.TypeSet, Optional: true, - ForceNew: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "elb_name": { @@ -309,7 +307,6 @@ func ResourceService() *schema.Resource { "propagate_tags": { Type: schema.TypeString, Optional: true, - ForceNew: true, DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { if old == "NONE" && new == "" { return true @@ -335,7 +332,6 @@ func ResourceService() *schema.Resource { "service_registries": { Type: schema.TypeList, Optional: true, - ForceNew: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ From 19e79d49bfbebe2891af301d61b2a3a7d32d1631 Mon Sep 17 00:00:00 2001 From: zachfeld Date: Wed, 9 Mar 2022 18:42:26 -0500 Subject: [PATCH 177/229] r/aws_ecs_service: rebase onto main --- internal/service/ecs/service.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/internal/service/ecs/service.go b/internal/service/ecs/service.go index 6bb0d437189..7b83463c0d4 100644 --- a/internal/service/ecs/service.go +++ b/internal/service/ecs/service.go @@ -316,7 +316,7 @@ func ResourceService() *schema.Resource { ValidateFunc: validation.StringInSlice([]string{ ecs.PropagateTagsService, ecs.PropagateTagsTaskDefinition, - "", + ecs.PropagateTagsNone, }, false), }, "scheduling_strategy": { @@ -1107,6 +1107,26 @@ func resourceServiceUpdate(d *schema.ResourceData, meta interface{}) error { input.EnableExecuteCommand = aws.Bool(d.Get("enable_execute_command").(bool)) } + if d.HasChange("enable_ecs_managed_tags") { + updateService = true + input.EnableECSManagedTags = aws.Bool(d.Get("enable_ecs_managed_tags").(bool)) + } + + if d.HasChange("load_balancer") { + updateService = true + input.LoadBalancers = expandLoadBalancers(d.Get("load_balancer").([]interface{})) + } + + if d.HasChange("propagate_tags") { + updateService = true + input.PropagateTags = aws.String(d.Get("propagate_tags").(string)) + } + + if d.HasChange("service_registries") { + updateService = true + input.ServiceRegistries = expandServiceRegistries(d.Get("service_registries").([]interface{})) + } + if updateService { log.Printf("[DEBUG] Updating ECS Service (%s): %s", d.Id(), input) // Retry due to IAM eventual consistency From f565613c18c94aeab7930708e42e3ae9beefa68a Mon Sep 17 00:00:00 2001 From: zachfeld Date: Wed, 9 Mar 2022 22:39:58 -0500 Subject: [PATCH 178/229] r/aws_ecs_service: update TestAccECSService_Tags_propagate to test ecs.PropagateTagsNone --- internal/service/ecs/service_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/ecs/service_test.go b/internal/service/ecs/service_test.go index 76ebdadc59d..8e7846a073a 100644 --- a/internal/service/ecs/service_test.go +++ b/internal/service/ecs/service_test.go @@ -1233,10 +1233,10 @@ func TestAccECSService_Tags_propagate(t *testing.T) { ), }, { - Config: testAccServiceManagedTagsConfig(rName), + Config: testAccServicePropagateTagsConfig(rName, "NONE"), Check: resource.ComposeTestCheckFunc( testAccCheckServiceExists(resourceName, &third), - resource.TestCheckResourceAttr(resourceName, "propagate_tags", "NONE"), + resource.TestCheckResourceAttr(resourceName, "propagate_tags", ecs.PropagateTagsNone), ), }, }, From 4cb37a1717aa7a536716d3f44ef44c42841343ef Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 09:14:40 -0400 Subject: [PATCH 179/229] Explicitly set vpc_subnet_ids to avoid errors like The availability zones of the specified subnets in the launch template and the Auto Scaling group do not match''. --- .../gamelift/game_server_group_test.go | 53 +++++++++++++++---- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/internal/service/gamelift/game_server_group_test.go b/internal/service/gamelift/game_server_group_test.go index b5c9a2f8ba0..d36d2a2d739 100644 --- a/internal/service/gamelift/game_server_group_test.go +++ b/internal/service/gamelift/game_server_group_test.go @@ -628,9 +628,24 @@ resource "aws_iam_role_policy_attachment" %[2]q { func testAccGameliftGameServerGroupLaunchTemplateConfig(rName string) string { return fmt.Sprintf(` +data "aws_vpc" "test" { + default = true +} + +data "aws_subnets" "test" { + filter { + name = "vpc-id" + values = [data.aws_vpc.test.id] + } +} + resource "aws_launch_template" "test" { image_id = data.aws_ami.amzn-ami-minimal-hvm-ebs.id name = %[1]q + + network_interfaces { + subnet_id = data.aws_subnets.test.ids[0] + } } `, rName) } @@ -669,6 +684,8 @@ resource "aws_gamelift_game_server_group" "test" { min_size = 1 role_arn = aws_iam_role.test.arn + vpc_subnets = [data.aws_subnets.test.ids[0]] + depends_on = [aws_iam_role_policy_attachment.test] } `, rName)) @@ -702,6 +719,8 @@ resource "aws_gamelift_game_server_group" "test" { min_size = 1 role_arn = aws_iam_role.test.arn + vpc_subnets = [data.aws_subnets.test.ids[0]] + depends_on = [aws_iam_role_policy_attachment.test] } `, rName)) @@ -736,6 +755,8 @@ resource "aws_gamelift_game_server_group" "test" { min_size = 1 role_arn = aws_iam_role.test.arn + vpc_subnets = [data.aws_subnets.test.ids[0]] + depends_on = [aws_iam_role_policy_attachment.test] } `, rName)) @@ -765,6 +786,8 @@ resource "aws_gamelift_game_server_group" "test" { min_size = 1 role_arn = aws_iam_role.test.arn + vpc_subnets = [data.aws_subnets.test.ids[0]] + depends_on = [aws_iam_role_policy_attachment.test] } `, rName, balancingStrategy)) @@ -793,6 +816,8 @@ resource "aws_gamelift_game_server_group" "test" { min_size = 1 role_arn = aws_iam_role.test.arn + vpc_subnets = [data.aws_subnets.test.ids[0]] + depends_on = [aws_iam_role_policy_attachment.test] } `, gameServerGroupName)) @@ -821,6 +846,8 @@ resource "aws_gamelift_game_server_group" "test" { min_size = 1 role_arn = aws_iam_role.test.arn + vpc_subnets = [data.aws_subnets.test.ids[0]] + depends_on = [aws_iam_role_policy_attachment.test] } `, rName, count)) @@ -850,6 +877,8 @@ resource "aws_gamelift_game_server_group" "test" { min_size = 1 role_arn = aws_iam_role.test.arn + vpc_subnets = [data.aws_subnets.test.ids[0]] + depends_on = [aws_iam_role_policy_attachment.test] } `, rName, weightedCapacity)) @@ -878,6 +907,8 @@ resource "aws_gamelift_game_server_group" "test" { min_size = 1 role_arn = aws_iam_role.test.arn + vpc_subnets = [data.aws_subnets.test.ids[0]] + depends_on = [aws_iam_role_policy_attachment.test] } `, rName)) @@ -906,6 +937,8 @@ resource "aws_gamelift_game_server_group" "test" { min_size = 1 role_arn = aws_iam_role.test.arn + vpc_subnets = [data.aws_subnets.test.ids[0]] + depends_on = [aws_iam_role_policy_attachment.test] } `, rName)) @@ -935,6 +968,8 @@ resource "aws_gamelift_game_server_group" "test" { min_size = 1 role_arn = aws_iam_role.test.arn + vpc_subnets = [data.aws_subnets.test.ids[0]] + depends_on = [aws_iam_role_policy_attachment.test] } `, rName)) @@ -963,6 +998,8 @@ resource "aws_gamelift_game_server_group" "test" { min_size = 1 role_arn = aws_iam_role.test.arn + vpc_subnets = [data.aws_subnets.test.ids[0]] + depends_on = [aws_iam_role_policy_attachment.test] } `, rName, maxSize)) @@ -991,6 +1028,8 @@ resource "aws_gamelift_game_server_group" "test" { min_size = %[2]s role_arn = aws_iam_role.test.arn + vpc_subnets = [data.aws_subnets.test.ids[0]] + depends_on = [aws_iam_role_policy_attachment.test] } `, rName, minSize)) @@ -1052,6 +1091,8 @@ resource "aws_gamelift_game_server_group" "test" { min_size = 1 role_arn = aws_iam_role.test.arn + vpc_subnets = [data.aws_subnets.test.ids[0]] + depends_on = [aws_iam_role_policy_attachment.test] } `, rName, gameServerProtectionPolicy)) @@ -1080,6 +1121,8 @@ resource "aws_gamelift_game_server_group" "test" { min_size = 1 role_arn = aws_iam_role.%[2]s.arn + vpc_subnets = [data.aws_subnets.test.ids[0]] + depends_on = [aws_iam_role_policy_attachment.%[2]s] } `, rName, roleArn)) @@ -1092,14 +1135,6 @@ func testAccGameliftGameServerGroupConfigVpcSubnets(rName string, count int) str testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), testAccGameliftGameServerGroupLaunchTemplateConfig(rName), fmt.Sprintf(` -data "aws_vpc" "test" { - default = true -} - -data "aws_subnet_ids" "test" { - vpc_id = data.aws_vpc.test.id -} - resource "aws_gamelift_game_server_group" "test" { game_server_group_name = %[1]q dynamic "instance_definition" { @@ -1115,7 +1150,7 @@ resource "aws_gamelift_game_server_group" "test" { max_size = 1 min_size = 1 role_arn = aws_iam_role.test.arn - vpc_subnets = slice(tolist(data.aws_subnet_ids.test.ids), 0, %[2]d) + vpc_subnets = slice(data.aws_subnets.test.ids, 0, %[2]d) depends_on = [aws_iam_role_policy_attachment.test] } From 97ef7e7e8fa9dc6ce2647b8dbc2a3d981d6811a9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 09:36:05 -0400 Subject: [PATCH 180/229] Remove 'testAccGameliftGameServerGroupConfigTags' as it's not used. --- .../gamelift/game_server_group_test.go | 32 ------------------- 1 file changed, 32 deletions(-) diff --git a/internal/service/gamelift/game_server_group_test.go b/internal/service/gamelift/game_server_group_test.go index d36d2a2d739..09455aa0c19 100644 --- a/internal/service/gamelift/game_server_group_test.go +++ b/internal/service/gamelift/game_server_group_test.go @@ -1035,38 +1035,6 @@ resource "aws_gamelift_game_server_group" "test" { `, rName, minSize)) } -func testAccGameliftGameServerGroupConfigTags(rName string, key string, value string) string { - return acctest.ConfigCompose( - acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), - testAccGameliftGameServerGroupIamConfig(rName, "test"), - testAccGameliftGameServerGroupInstanceTypeOfferingsConfig(), - testAccGameliftGameServerGroupLaunchTemplateConfig(rName), - fmt.Sprintf(` -resource "aws_gamelift_game_server_group" "test" { - game_server_group_name = %[1]q - dynamic "instance_definition" { - for_each = data.aws_ec2_instance_type_offerings.available.instance_types - content { - instance_type = instance_definition.value - } - } - launch_template { - id = aws_launch_template.test.id - } - - max_size = 1 - min_size = 1 - role_arn = aws_iam_role.test.arn - - tags = { - %[2]s = %[3]q - } - - depends_on = [aws_iam_role_policy_attachment.test] -} -`, rName, key, value)) -} - func testAccGameliftGameServerGroupConfigGameServerProtectionPolicy(rName string, gameServerProtectionPolicy string) string { return acctest.ConfigCompose( acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), From de8c5b78aae0311b457b75104611d9d73f0fe230 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 09:26:06 -0400 Subject: [PATCH 181/229] Add CHANGELOG entry. --- .changelog/23600.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/23600.txt diff --git a/.changelog/23600.txt b/.changelog/23600.txt new file mode 100644 index 00000000000..1fe84f981b3 --- /dev/null +++ b/.changelog/23600.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_ecs_service: `enable_ecs_managed_tags`, `load_balancer`, `propagate_tags` and `service_registries` can now be updated in-place +``` \ No newline at end of file From 937eca2c3c2a2c65b2f7dba5d6456a10e821222b Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 09:43:47 -0400 Subject: [PATCH 182/229] Use '_Values' for validations (#14601). --- internal/service/ecs/service.go | 52 +++++++++++---------------------- 1 file changed, 17 insertions(+), 35 deletions(-) diff --git a/internal/service/ecs/service.go b/internal/service/ecs/service.go index 7b83463c0d4..35bd263ce0a 100644 --- a/internal/service/ecs/service.go +++ b/internal/service/ecs/service.go @@ -107,15 +107,11 @@ func ResourceService() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "type": { - Type: schema.TypeString, - ForceNew: true, - Optional: true, - Default: ecs.DeploymentControllerTypeEcs, - ValidateFunc: validation.StringInSlice([]string{ - ecs.DeploymentControllerTypeCodeDeploy, - ecs.DeploymentControllerTypeEcs, - ecs.DeploymentControllerTypeExternal, - }, false), + Type: schema.TypeString, + ForceNew: true, + Optional: true, + Default: ecs.DeploymentControllerTypeEcs, + ValidateFunc: validation.StringInSlice(ecs.DeploymentControllerType_Values(), false), }, }, }, @@ -253,13 +249,9 @@ func ResourceService() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "type": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice([]string{ - ecs.PlacementStrategyTypeBinpack, - ecs.PlacementStrategyTypeRandom, - ecs.PlacementStrategyTypeSpread, - }, false), + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(ecs.PlacementStrategyType_Values(), false), }, "field": { Type: schema.TypeString, @@ -289,12 +281,9 @@ func ResourceService() *schema.Resource { Optional: true, }, "type": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice([]string{ - ecs.PlacementConstraintTypeDistinctInstance, - ecs.PlacementConstraintTypeMemberOf, - }, false), + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(ecs.PlacementConstraintType_Values(), false), }, }, }, @@ -313,21 +302,14 @@ func ResourceService() *schema.Resource { } return false }, - ValidateFunc: validation.StringInSlice([]string{ - ecs.PropagateTagsService, - ecs.PropagateTagsTaskDefinition, - ecs.PropagateTagsNone, - }, false), + ValidateFunc: validation.StringInSlice(ecs.PropagateTags_Values(), false), }, "scheduling_strategy": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Default: ecs.SchedulingStrategyReplica, - ValidateFunc: validation.StringInSlice([]string{ - ecs.SchedulingStrategyDaemon, - ecs.SchedulingStrategyReplica, - }, false), + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Default: ecs.SchedulingStrategyReplica, + ValidateFunc: validation.StringInSlice(ecs.SchedulingStrategy_Values(), false), }, "service_registries": { Type: schema.TypeList, From 4b21dcdee2cdf1c16883bd6308302ec888110c49 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 09:47:50 -0400 Subject: [PATCH 183/229] r/aws_ec2_service: Simplify update logic by using 'if d.HasChangesExcept("tags", "tags_all")'. --- internal/service/ecs/service.go | 202 +++++++++++++++----------------- 1 file changed, 92 insertions(+), 110 deletions(-) diff --git a/internal/service/ecs/service.go b/internal/service/ecs/service.go index 35bd263ce0a..a1abb886e6c 100644 --- a/internal/service/ecs/service.go +++ b/internal/service/ecs/service.go @@ -978,142 +978,124 @@ func flattenServiceRegistries(srs []*ecs.ServiceRegistry) []map[string]interface func resourceServiceUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).ECSConn - updateService := false - input := ecs.UpdateServiceInput{ - Cluster: aws.String(d.Get("cluster").(string)), - ForceNewDeployment: aws.Bool(d.Get("force_new_deployment").(bool)), - Service: aws.String(d.Id()), - } + if d.HasChangesExcept("tags", "tags_all") { + input := &ecs.UpdateServiceInput{ + Cluster: aws.String(d.Get("cluster").(string)), + ForceNewDeployment: aws.Bool(d.Get("force_new_deployment").(bool)), + Service: aws.String(d.Id()), + } - schedulingStrategy := d.Get("scheduling_strategy").(string) + schedulingStrategy := d.Get("scheduling_strategy").(string) - if schedulingStrategy == ecs.SchedulingStrategyDaemon { - if d.HasChange("deployment_minimum_healthy_percent") { - updateService = true - input.DeploymentConfiguration = &ecs.DeploymentConfiguration{ - MinimumHealthyPercent: aws.Int64(int64(d.Get("deployment_minimum_healthy_percent").(int))), + if schedulingStrategy == ecs.SchedulingStrategyDaemon { + if d.HasChange("deployment_minimum_healthy_percent") { + input.DeploymentConfiguration = &ecs.DeploymentConfiguration{ + MinimumHealthyPercent: aws.Int64(int64(d.Get("deployment_minimum_healthy_percent").(int))), + } + } + } else if schedulingStrategy == ecs.SchedulingStrategyReplica { + if d.HasChange("desired_count") { + input.DesiredCount = aws.Int64(int64(d.Get("desired_count").(int))) } - } - } else if schedulingStrategy == ecs.SchedulingStrategyReplica { - if d.HasChange("desired_count") { - updateService = true - input.DesiredCount = aws.Int64(int64(d.Get("desired_count").(int))) - } - if d.HasChanges("deployment_maximum_percent", "deployment_minimum_healthy_percent") { - updateService = true - input.DeploymentConfiguration = &ecs.DeploymentConfiguration{ - MaximumPercent: aws.Int64(int64(d.Get("deployment_maximum_percent").(int))), - MinimumHealthyPercent: aws.Int64(int64(d.Get("deployment_minimum_healthy_percent").(int))), + if d.HasChanges("deployment_maximum_percent", "deployment_minimum_healthy_percent") { + input.DeploymentConfiguration = &ecs.DeploymentConfiguration{ + MaximumPercent: aws.Int64(int64(d.Get("deployment_maximum_percent").(int))), + MinimumHealthyPercent: aws.Int64(int64(d.Get("deployment_minimum_healthy_percent").(int))), + } } } - } - - if d.HasChange("deployment_circuit_breaker") { - updateService = true - if input.DeploymentConfiguration == nil { - input.DeploymentConfiguration = &ecs.DeploymentConfiguration{} - } + if d.HasChange("deployment_circuit_breaker") { + if input.DeploymentConfiguration == nil { + input.DeploymentConfiguration = &ecs.DeploymentConfiguration{} + } - // To remove an existing deployment circuit breaker, specify an empty object. - input.DeploymentConfiguration.DeploymentCircuitBreaker = &ecs.DeploymentCircuitBreaker{} + // To remove an existing deployment circuit breaker, specify an empty object. + input.DeploymentConfiguration.DeploymentCircuitBreaker = &ecs.DeploymentCircuitBreaker{} - if v, ok := d.GetOk("deployment_circuit_breaker"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - input.DeploymentConfiguration.DeploymentCircuitBreaker = expandDeploymentCircuitBreaker(v.([]interface{})[0].(map[string]interface{})) + if v, ok := d.GetOk("deployment_circuit_breaker"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.DeploymentConfiguration.DeploymentCircuitBreaker = expandDeploymentCircuitBreaker(v.([]interface{})[0].(map[string]interface{})) + } } - } - if d.HasChange("ordered_placement_strategy") { - updateService = true - // Reference: https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateService.html#ECS-UpdateService-request-placementStrategy - // To remove an existing placement strategy, specify an empty object. - input.PlacementStrategy = []*ecs.PlacementStrategy{} + if d.HasChange("ordered_placement_strategy") { + // Reference: https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateService.html#ECS-UpdateService-request-placementStrategy + // To remove an existing placement strategy, specify an empty object. + input.PlacementStrategy = []*ecs.PlacementStrategy{} - if v, ok := d.GetOk("ordered_placement_strategy"); ok && len(v.([]interface{})) > 0 { - ps, err := expandPlacementStrategy(v.([]interface{})) + if v, ok := d.GetOk("ordered_placement_strategy"); ok && len(v.([]interface{})) > 0 { + ps, err := expandPlacementStrategy(v.([]interface{})) - if err != nil { - return err - } + if err != nil { + return err + } - input.PlacementStrategy = ps + input.PlacementStrategy = ps + } } - } - if d.HasChange("placement_constraints") { - updateService = true - // Reference: https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateService.html#ECS-UpdateService-request-placementConstraints - // To remove all existing placement constraints, specify an empty array. - input.PlacementConstraints = []*ecs.PlacementConstraint{} + if d.HasChange("placement_constraints") { + // Reference: https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateService.html#ECS-UpdateService-request-placementConstraints + // To remove all existing placement constraints, specify an empty array. + input.PlacementConstraints = []*ecs.PlacementConstraint{} - if v, ok := d.Get("placement_constraints").(*schema.Set); ok && v.Len() > 0 { - pc, err := expandPlacementConstraints(v.List()) + if v, ok := d.Get("placement_constraints").(*schema.Set); ok && v.Len() > 0 { + pc, err := expandPlacementConstraints(v.List()) - if err != nil { - return err - } + if err != nil { + return err + } - input.PlacementConstraints = pc + input.PlacementConstraints = pc + } } - } - if d.HasChange("platform_version") { - updateService = true - input.PlatformVersion = aws.String(d.Get("platform_version").(string)) - } + if d.HasChange("platform_version") { + input.PlatformVersion = aws.String(d.Get("platform_version").(string)) + } - if d.HasChange("health_check_grace_period_seconds") { - updateService = true - input.HealthCheckGracePeriodSeconds = aws.Int64(int64(d.Get("health_check_grace_period_seconds").(int))) - } + if d.HasChange("health_check_grace_period_seconds") { + input.HealthCheckGracePeriodSeconds = aws.Int64(int64(d.Get("health_check_grace_period_seconds").(int))) + } - if d.HasChange("task_definition") { - updateService = true - input.TaskDefinition = aws.String(d.Get("task_definition").(string)) - } + if d.HasChange("task_definition") { + input.TaskDefinition = aws.String(d.Get("task_definition").(string)) + } - if d.HasChange("network_configuration") { - updateService = true - input.NetworkConfiguration = expandNetworkConfiguration(d.Get("network_configuration").([]interface{})) - } + if d.HasChange("network_configuration") { + input.NetworkConfiguration = expandNetworkConfiguration(d.Get("network_configuration").([]interface{})) + } - if d.HasChange("capacity_provider_strategy") { - updateService = true - input.CapacityProviderStrategy = expandCapacityProviderStrategy(d.Get("capacity_provider_strategy").(*schema.Set)) - } + if d.HasChange("capacity_provider_strategy") { + input.CapacityProviderStrategy = expandCapacityProviderStrategy(d.Get("capacity_provider_strategy").(*schema.Set)) + } - if d.HasChange("enable_execute_command") { - updateService = true - input.EnableExecuteCommand = aws.Bool(d.Get("enable_execute_command").(bool)) - } + if d.HasChange("enable_execute_command") { + input.EnableExecuteCommand = aws.Bool(d.Get("enable_execute_command").(bool)) + } - if d.HasChange("enable_ecs_managed_tags") { - updateService = true - input.EnableECSManagedTags = aws.Bool(d.Get("enable_ecs_managed_tags").(bool)) - } + if d.HasChange("enable_ecs_managed_tags") { + input.EnableECSManagedTags = aws.Bool(d.Get("enable_ecs_managed_tags").(bool)) + } - if d.HasChange("load_balancer") { - updateService = true - input.LoadBalancers = expandLoadBalancers(d.Get("load_balancer").([]interface{})) - } + if d.HasChange("load_balancer") { + input.LoadBalancers = expandLoadBalancers(d.Get("load_balancer").([]interface{})) + } - if d.HasChange("propagate_tags") { - updateService = true - input.PropagateTags = aws.String(d.Get("propagate_tags").(string)) - } + if d.HasChange("propagate_tags") { + input.PropagateTags = aws.String(d.Get("propagate_tags").(string)) + } - if d.HasChange("service_registries") { - updateService = true - input.ServiceRegistries = expandServiceRegistries(d.Get("service_registries").([]interface{})) - } + if d.HasChange("service_registries") { + input.ServiceRegistries = expandServiceRegistries(d.Get("service_registries").([]interface{})) + } - if updateService { log.Printf("[DEBUG] Updating ECS Service (%s): %s", d.Id(), input) // Retry due to IAM eventual consistency err := resource.Retry(tfiam.PropagationTimeout+serviceUpdateTimeout, func() *resource.RetryError { - _, err := conn.UpdateService(&input) + _, err := conn.UpdateService(input) if err != nil { if tfawserr.ErrMessageContains(err, ecs.ErrCodeInvalidParameterException, "verify that the ECS service role being passed has the proper permissions") { @@ -1130,22 +1112,22 @@ func resourceServiceUpdate(d *schema.ResourceData, meta interface{}) error { }) if tfresource.TimedOut(err) { - _, err = conn.UpdateService(&input) + _, err = conn.UpdateService(input) } if err != nil { return fmt.Errorf("error updating ECS Service (%s): %w", d.Id(), err) } - } - if d.Get("wait_for_steady_state").(bool) { - cluster := "" - if v, ok := d.GetOk("cluster"); ok { - cluster = v.(string) - } + if d.Get("wait_for_steady_state").(bool) { + cluster := "" + if v, ok := d.GetOk("cluster"); ok { + cluster = v.(string) + } - if err := waitServiceStable(conn, d.Id(), cluster); err != nil { - return fmt.Errorf("error waiting for ECS service (%s) to become ready: %w", d.Id(), err) + if err := waitServiceStable(conn, d.Id(), cluster); err != nil { + return fmt.Errorf("error waiting for ECS service (%s) to become ready: %w", d.Id(), err) + } } } From 3095ac20530fdac8628046607b14072d80c0866c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 09:51:52 -0400 Subject: [PATCH 184/229] Add 'ImportStateVerifyIgnore: []string{"vpc_subnets"}'. --- .../gamelift/game_server_group_test.go | 98 +++++++++++-------- 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/internal/service/gamelift/game_server_group_test.go b/internal/service/gamelift/game_server_group_test.go index 09455aa0c19..216922683bc 100644 --- a/internal/service/gamelift/game_server_group_test.go +++ b/internal/service/gamelift/game_server_group_test.go @@ -43,9 +43,10 @@ func TestAccGameliftGameServerGroup_basic(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"vpc_subnets"}, }, }, }) @@ -74,9 +75,10 @@ func TestAccGameliftGameServerGroup_AutoScalingPolicy(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"vpc_subnets"}, }, }, }) @@ -105,9 +107,10 @@ func TestAccGameliftGameServerGroup_AutoScalingPolicy_EstimatedInstanceWarmup(t ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"vpc_subnets"}, }, }, }) @@ -135,9 +138,10 @@ func TestAccGameliftGameServerGroup_BalancingStrategy(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"vpc_subnets"}, }, }, }) @@ -165,9 +169,10 @@ func TestAccGameliftGameServerGroup_GameServerGroupName(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"vpc_subnets"}, }, { Config: testAccGameliftGameServerGroupConfigGameServerGroupName(rName, rName+"-new"), @@ -202,9 +207,10 @@ func TestAccGameliftGameServerGroup_InstanceDefinition(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"vpc_subnets"}, }, { Config: testAccGameliftGameServerGroupConfigInstanceDefinition(rName, 3), @@ -241,9 +247,10 @@ func TestAccGameliftGameServerGroup_InstanceDefinition_WeightedCapacity(t *testi ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"vpc_subnets"}, }, { Config: testAccGameliftGameServerGroupConfigInstanceDefinitionWeightedCapacity(rName, "2"), @@ -282,9 +289,10 @@ func TestAccGameliftGameServerGroup_LaunchTemplate_Id(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"vpc_subnets"}, }, }, }) @@ -314,9 +322,10 @@ func TestAccGameliftGameServerGroup_LaunchTemplate_Name(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"vpc_subnets"}, }, }, }) @@ -346,9 +355,10 @@ func TestAccGameliftGameServerGroup_LaunchTemplate_Version(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"vpc_subnets"}, }, }, }) @@ -376,9 +386,10 @@ func TestAccGameliftGameServerGroup_GameServerProtectionPolicy(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"vpc_subnets"}, }, }, }) @@ -406,9 +417,10 @@ func TestAccGameliftGameServerGroup_MaxSize(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"vpc_subnets"}, }, { Config: testAccGameliftGameServerGroupConfigMaxSize(rName, "2"), @@ -443,9 +455,10 @@ func TestAccGameliftGameServerGroup_MinSize(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"vpc_subnets"}, }, { Config: testAccGameliftGameServerGroupConfigMinSize(rName, "2"), @@ -481,9 +494,10 @@ func TestAccGameliftGameServerGroup_RoleArn(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"vpc_subnets"}, }, { Config: testAccGameliftGameServerGroupConfigRoleArn(rName, "test2"), From 5daed5c38796dff36a070926ae0b120750abd811 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 11:30:01 -0400 Subject: [PATCH 185/229] Use 'customdiff.ComputedIf'. --- internal/service/kafka/configuration.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/internal/service/kafka/configuration.go b/internal/service/kafka/configuration.go index b2fb0120ea7..4d918e060bb 100644 --- a/internal/service/kafka/configuration.go +++ b/internal/service/kafka/configuration.go @@ -24,13 +24,11 @@ func ResourceConfiguration() *schema.Resource { Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, + CustomizeDiff: customdiff.Sequence( - func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error { - if diff.HasChange("server_properties") { - return diff.SetNewComputed("latest_revision") - } - return nil - }, + customdiff.ComputedIf("latest_revision", func(_ context.Context, diff *schema.ResourceDiff, meta interface{}) bool { + return diff.HasChange("server_properties") + }), ), Schema: map[string]*schema.Schema{ From 7ff05891370aa9119717140c06fa16b062649cc5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 11:34:16 -0400 Subject: [PATCH 186/229] Add CHANGELOG entry. --- .changelog/23662.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/23662.txt diff --git a/.changelog/23662.txt b/.changelog/23662.txt new file mode 100644 index 00000000000..10aba5e828c --- /dev/null +++ b/.changelog/23662.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_msk_configuration: Correctly set `latest_revision` as Computed when `server_properties` changes +``` \ No newline at end of file From 4ed3b491c41e44628fb61ac4161db1c31408229d Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 12:21:18 -0400 Subject: [PATCH 187/229] Add CHANGELOG entry. --- .changelog/23440.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/23440.txt diff --git a/.changelog/23440.txt b/.changelog/23440.txt new file mode 100644 index 00000000000..25692d56289 --- /dev/null +++ b/.changelog/23440.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_iot_topic_rule: Add `cloudwatch_logs` and `error_action.cloudwatch_logs` arguments +``` \ No newline at end of file From 6e0d54e01f8812b2f9f31359311df5f47a4069de Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Mar 2022 12:49:28 -0500 Subject: [PATCH 188/229] rds: Fix some acceptance tests --- internal/service/rds/cluster.go | 7 + internal/service/rds/cluster_endpoint_test.go | 22 +- internal/service/rds/cluster_test.go | 2 +- internal/service/rds/global_cluster.go | 5 +- internal/service/rds/global_cluster_test.go | 41 +-- .../service/rds/instance_data_source_test.go | 27 +- internal/service/rds/instance_test.go | 6 +- internal/service/rds/option_group_test.go | 284 +++++++++--------- 8 files changed, 210 insertions(+), 184 deletions(-) diff --git a/internal/service/rds/cluster.go b/internal/service/rds/cluster.go index 16cfd9d0736..d7d9e5874f2 100644 --- a/internal/service/rds/cluster.go +++ b/internal/service/rds/cluster.go @@ -559,6 +559,7 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { } if attr, ok := d.GetOk("engine_version"); ok { + fmt.Printf("[CREATE/cluster/snapshot_identifier] engine_version: %s\n", attr.(string)) opts.EngineVersion = aws.String(attr.(string)) } @@ -654,6 +655,7 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { } if attr, ok := d.GetOk("engine_version"); ok { + fmt.Printf("[CREATE/cluster/s3_import] engine_version: %s\n", attr.(string)) createOpts.EngineVersion = aws.String(attr.(string)) } @@ -871,6 +873,7 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { } if attr, ok := d.GetOk("engine_version"); ok { + fmt.Printf("[CREATE/cluster/else] engine_version: %s\n", attr.(string)) createOpts.EngineVersion = aws.String(attr.(string)) } @@ -1183,6 +1186,7 @@ func resourceClusterUpdate(d *schema.ResourceData, meta interface{}) error { } if d.HasChange("engine_version") { + fmt.Printf("[UPDATE/cluster] engine_version: %s\n", d.Get("engine_version").(string)) req.EngineVersion = aws.String(d.Get("engine_version").(string)) requestUpdate = true } @@ -1549,7 +1553,10 @@ func compareActualEngineVersion(d *schema.ResourceData, oldVersion string, newVe if oldVersion != newVersion && string(append([]byte(oldVersion), []byte(".")...)) != newVersionSubstr { d.Set("engine_version", newVersion) + fmt.Printf("[READ/cluster] engine_version: %s\n", newVersion) } d.Set("engine_version_actual", newVersion) + fmt.Printf("[READ/cluster] engine_version_actual: %s\n", newVersion) + } diff --git a/internal/service/rds/cluster_endpoint_test.go b/internal/service/rds/cluster_endpoint_test.go index 02e74881f79..c463959741a 100644 --- a/internal/service/rds/cluster_endpoint_test.go +++ b/internal/service/rds/cluster_endpoint_test.go @@ -211,7 +211,9 @@ func testAccCheckClusterEndpointExistsWithProvider(resourceName string, endpoint } func testAccClusterEndpointBaseConfig(n int) string { - return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` + return acctest.ConfigCompose( + acctest.ConfigAvailableAZsNoOptIn(), + fmt.Sprintf(` data "aws_rds_orderable_db_instance" "test" { engine = aws_rds_cluster.default.engine engine_version = aws_rds_cluster.default.engine_version @@ -249,7 +251,9 @@ resource "aws_rds_cluster_instance" "test2" { } func testAccClusterEndpointConfig(n int) string { - return testAccClusterEndpointBaseConfig(n) + fmt.Sprintf(` + return acctest.ConfigCompose( + testAccClusterEndpointBaseConfig(n), + fmt.Sprintf(` resource "aws_rds_cluster_endpoint" "reader" { cluster_identifier = aws_rds_cluster.default.id cluster_endpoint_identifier = "reader-%[1]d" @@ -265,11 +269,13 @@ resource "aws_rds_cluster_endpoint" "default" { excluded_members = [aws_rds_cluster_instance.test2.id] } -`, n) +`, n)) } func testAccClusterEndpointTags1Config(n int, tagKey1, tagValue1 string) string { - return testAccClusterEndpointBaseConfig(n) + fmt.Sprintf(` + return acctest.ConfigCompose( + testAccClusterEndpointBaseConfig(n), + fmt.Sprintf(` resource "aws_rds_cluster_endpoint" "reader" { cluster_identifier = aws_rds_cluster.default.id cluster_endpoint_identifier = "reader-%[1]d" @@ -281,11 +287,13 @@ resource "aws_rds_cluster_endpoint" "reader" { %[2]q = %[3]q } } -`, n, tagKey1, tagValue1) +`, n, tagKey1, tagValue1)) } func testAccClusterEndpointTags2Config(n int, tagKey1, tagValue1, tagKey2, tagValue2 string) string { - return testAccClusterEndpointBaseConfig(n) + fmt.Sprintf(` + return acctest.ConfigCompose( + testAccClusterEndpointBaseConfig(n), + fmt.Sprintf(` resource "aws_rds_cluster_endpoint" "reader" { cluster_identifier = aws_rds_cluster.default.id cluster_endpoint_identifier = "reader-%[1]d" @@ -298,5 +306,5 @@ resource "aws_rds_cluster_endpoint" "reader" { %[4]q = %[5]q } } -`, n, tagKey1, tagValue1, tagKey2, tagValue2) +`, n, tagKey1, tagValue1, tagKey2, tagValue2)) } diff --git a/internal/service/rds/cluster_test.go b/internal/service/rds/cluster_test.go index 401660d83e7..0ac9a15bc8a 100644 --- a/internal/service/rds/cluster_test.go +++ b/internal/service/rds/cluster_test.go @@ -3599,7 +3599,7 @@ func testAccClusterConfig_SnapshotIdentifier_EngineVersion(rName string, same bo return fmt.Sprintf(` data "aws_rds_engine_version" "test" { engine = "aurora-postgresql" - preferred_versions = ["11.4", "10.4", "9.6.6"] + preferred_versions = ["13.3", "12.9", "11.14"] } data "aws_rds_engine_version" "upgrade" { diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index 8d5806da3da..674f4e6fa79 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -128,6 +128,7 @@ func resourceGlobalClusterCreate(d *schema.ResourceData, meta interface{}) error } if v, ok := d.GetOk("engine_version"); ok { + fmt.Printf("[CREATE/global_cluster] engine_version: %s\n", v.(string)) input.EngineVersion = aws.String(v.(string)) } @@ -192,6 +193,7 @@ func resourceGlobalClusterRead(d *schema.ResourceData, meta interface{}) error { d.Set("deletion_protection", globalCluster.DeletionProtection) d.Set("engine", globalCluster.Engine) d.Set("engine_version", globalCluster.EngineVersion) + fmt.Printf("[READ/global_cluster] engine_verison: %s\n", aws.StringValue(globalCluster.EngineVersion)) d.Set("global_cluster_identifier", globalCluster.GlobalClusterIdentifier) if err := d.Set("global_cluster_members", flattenGlobalClusterMembers(globalCluster.GlobalClusterMembers)); err != nil { @@ -213,6 +215,7 @@ func resourceGlobalClusterUpdate(d *schema.ResourceData, meta interface{}) error } if d.HasChange("engine_version") { + fmt.Printf("[UPDATE/global_cluster] engine_version: %s\n", d.Get("engine_version").(string)) if err := resourceGlobalClusterUpgradeEngineVersion(d, conn); err != nil { return err } @@ -581,7 +584,7 @@ func resourceGlobalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, } } if err != nil { - return fmt.Errorf("Failed to update engine_version on global cluster member (%s): %s", clusterMemberArn, err) + return fmt.Errorf("failed to update engine_version on RDS Global Cluster member (%s): %s", clusterMemberArn, err) } } } diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index 893f88d74bd..586ffe58f26 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -210,17 +210,17 @@ func TestAccRDSGlobalCluster_engineVersionUpdateMinor(t *testing.T) { CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.6.mysql_aurora.1.22.2"), + Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-mysql", "5.7.mysql_aurora.2.10.1"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), ), }, { - Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.6.mysql_aurora.1.23.2"), + Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-mysql", "5.7.mysql_aurora.2.10.2"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster2), testAccCheckGlobalClusterNotRecreated(&globalCluster1, &globalCluster2), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.6.mysql_aurora.1.23.2"), + resource.TestCheckResourceAttr(resourceName, "engine_version", "5.7.mysql_aurora.2.10.2"), ), }, { @@ -244,18 +244,18 @@ func TestAccRDSGlobalCluster_engineVersionUpdateMajor(t *testing.T) { CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.6.mysql_aurora.1.22.2"), + Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.7.mysql_aurora.2.10.2"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), ), }, { - Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.7.mysql_aurora.2.07.2"), + Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "8.0.mysql_aurora.3.01.0"), ExpectNonEmptyPlan: true, Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster2), testAccCheckGlobalClusterNotRecreated(&globalCluster1, &globalCluster2), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.7.mysql_aurora.2.07.2"), + resource.TestCheckResourceAttr(resourceName, "engine_version", "8.0.mysql_aurora.3.01.0"), ), }, { @@ -532,7 +532,7 @@ func testAccPreCheckGlobalCluster(t *testing.T) { func testAccGlobalClusterConfig(rName string) string { return fmt.Sprintf(` resource "aws_rds_global_cluster" "test" { - global_cluster_identifier = %q + global_cluster_identifier = %[1]q } `, rName) } @@ -540,8 +540,8 @@ resource "aws_rds_global_cluster" "test" { func testAccGlobalClusterDatabaseNameConfig(rName, databaseName string) string { return fmt.Sprintf(` resource "aws_rds_global_cluster" "test" { - database_name = %q - global_cluster_identifier = %q + database_name = %[1]q + global_cluster_identifier = %[2]q } `, databaseName, rName) } @@ -549,8 +549,8 @@ resource "aws_rds_global_cluster" "test" { func testAccGlobalClusterDeletionProtectionConfig(rName string, deletionProtection bool) string { return fmt.Sprintf(` resource "aws_rds_global_cluster" "test" { - deletion_protection = %t - global_cluster_identifier = %q + deletion_protection = %[1]t + global_cluster_identifier = %[2]q } `, deletionProtection, rName) } @@ -558,8 +558,8 @@ resource "aws_rds_global_cluster" "test" { func testAccGlobalClusterEngineConfig(rName, engine string) string { return fmt.Sprintf(` resource "aws_rds_global_cluster" "test" { - engine = %q - global_cluster_identifier = %q + engine = %[1]q + global_cluster_identifier = %[2]q } `, engine, rName) } @@ -567,9 +567,9 @@ resource "aws_rds_global_cluster" "test" { func testAccGlobalClusterEngineVersionConfig(rName, engine, engineVersion string) string { return fmt.Sprintf(` resource "aws_rds_global_cluster" "test" { - engine = %q - engine_version = %q - global_cluster_identifier = %q + engine = %[1]q + engine_version = %[2]q + global_cluster_identifier = %[3]q } `, engine, engineVersion, rName) } @@ -586,6 +586,8 @@ resource "aws_rds_cluster" "test" { apply_immediately = true allow_major_version_upgrade = true cluster_identifier = %[3]q + engine = %[1]q + engine_version = %[2]q master_password = "mustbeeightcharacters" master_username = "test" skip_final_snapshot = true @@ -600,6 +602,9 @@ resource "aws_rds_cluster" "test" { resource "aws_rds_cluster_instance" "test" { apply_immediately = true cluster_identifier = aws_rds_cluster.test.id + #cluster_identifier = %[3]q + engine = %[1]q + engine_version = %[2]q identifier = %[3]q instance_class = "db.r3.large" @@ -664,8 +669,8 @@ resource "aws_rds_global_cluster" "test" { func testAccGlobalClusterStorageEncryptedConfig(rName string, storageEncrypted bool) string { return fmt.Sprintf(` resource "aws_rds_global_cluster" "test" { - global_cluster_identifier = %q - storage_encrypted = %t + global_cluster_identifier = %[1]q + storage_encrypted = %[2]t } `, rName, storageEncrypted) } diff --git a/internal/service/rds/instance_data_source_test.go b/internal/service/rds/instance_data_source_test.go index 59164d71ac2..832f18ae86e 100644 --- a/internal/service/rds/instance_data_source_test.go +++ b/internal/service/rds/instance_data_source_test.go @@ -11,14 +11,15 @@ import ( ) func TestAccRDSInstanceDataSource_basic(t *testing.T) { - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), Providers: acctest.Providers, Steps: []resource.TestStep{ { - Config: testAccInstanceDataSourceConfig(rInt), + Config: testAccInstanceDataSourceConfig(rName), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "address"), resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "allocated_storage"), @@ -44,7 +45,7 @@ func TestAccRDSInstanceDataSource_basic(t *testing.T) { } func TestAccRDSInstanceDataSource_ec2Classic(t *testing.T) { - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); acctest.PreCheckEC2Classic(t) }, @@ -52,7 +53,7 @@ func TestAccRDSInstanceDataSource_ec2Classic(t *testing.T) { ProviderFactories: acctest.ProviderFactories, Steps: []resource.TestStep{ { - Config: testAccInstanceDataSourceConfig_ec2Classic(rInt), + Config: testAccInstanceDataSourceConfig_ec2Classic(rName), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr("data.aws_db_instance.bar", "db_subnet_group", ""), ), @@ -61,7 +62,7 @@ func TestAccRDSInstanceDataSource_ec2Classic(t *testing.T) { }) } -func testAccInstanceDataSourceConfig(rInt int) string { +func testAccInstanceDataSourceConfig(rName string) string { return fmt.Sprintf(` data "aws_rds_orderable_db_instance" "test" { engine = "mariadb" @@ -69,7 +70,7 @@ data "aws_rds_orderable_db_instance" "test" { } resource "aws_db_instance" "bar" { - identifier = "datasource-test-terraform-%d" + identifier = %[1]q allocated_storage = 10 engine = data.aws_rds_orderable_db_instance.test.engine @@ -94,21 +95,21 @@ resource "aws_db_instance" "bar" { data "aws_db_instance" "bar" { db_instance_identifier = aws_db_instance.bar.identifier } -`, rInt) +`, rName) } -func testAccInstanceDataSourceConfig_ec2Classic(rInt int) string { +func testAccInstanceDataSourceConfig_ec2Classic(rName string) string { return acctest.ConfigCompose( acctest.ConfigEC2ClassicRegionProvider(), fmt.Sprintf(` data "aws_rds_orderable_db_instance" "test" { engine = "mysql" - engine_version = "5.6.41" - preferred_instance_classes = ["db.m3.medium", "db.m3.large", "db.r3.large"] + engine_version = "8.0.25" + preferred_instance_classes = ["db.t2.micro", "db.m3.medium", "db.m3.large", "db.r3.large"] } resource "aws_db_instance" "bar" { - identifier = "foobarbaz-test-terraform-%[1]d" + identifier = %[1]q allocated_storage = 10 engine = data.aws_rds_orderable_db_instance.test.engine engine_version = data.aws_rds_orderable_db_instance.test.engine_version @@ -118,12 +119,12 @@ resource "aws_db_instance" "bar" { username = "foo" publicly_accessible = true security_group_names = ["default"] - parameter_group_name = "default.mysql5.6" + parameter_group_name = "default.mysql8.0" skip_final_snapshot = true } data "aws_db_instance" "bar" { db_instance_identifier = aws_db_instance.bar.identifier } -`, rInt)) +`, rName)) } diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index 0b3f177b1d4..63610423e33 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -6319,9 +6319,11 @@ resource "aws_db_instance" "test" { } func testAccInstanceConfig_ReplicateSourceDB_AllocatedStorage(rName string, allocatedStorage int) string { - return acctest.ConfigCompose(testAccInstanceConfig_orderableClassMySQL(), fmt.Sprintf(` + return acctest.ConfigCompose( + testAccInstanceConfig_orderableClassMySQL(), + fmt.Sprintf(` resource "aws_db_instance" "source" { - allocated_storage = 5 + allocated_storage = %[2]d backup_retention_period = 1 engine = data.aws_rds_orderable_db_instance.test.engine identifier = "%[1]s-source" diff --git a/internal/service/rds/option_group_test.go b/internal/service/rds/option_group_test.go index 9b6d461d38d..1789e519b32 100644 --- a/internal/service/rds/option_group_test.go +++ b/internal/service/rds/option_group_test.go @@ -18,7 +18,8 @@ import ( func TestAccRDSOptionGroup_basic(t *testing.T) { var v rds.OptionGroup - rName := fmt.Sprintf("option-group-test-terraform-%s", sdkacctest.RandString(5)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -29,18 +30,18 @@ func TestAccRDSOptionGroup_basic(t *testing.T) { { Config: testAccOptionGroupBasicConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - acctest.MatchResourceAttrRegionalARN("aws_db_option_group.bar", "arn", "rds", regexp.MustCompile(`og:.+`)), - resource.TestCheckResourceAttr("aws_db_option_group.bar", "engine_name", "mysql"), - resource.TestCheckResourceAttr("aws_db_option_group.bar", "major_engine_version", "5.6"), - resource.TestCheckResourceAttr("aws_db_option_group.bar", "name", rName), - resource.TestCheckResourceAttr("aws_db_option_group.bar", "option.#", "0"), - resource.TestCheckResourceAttr("aws_db_option_group.bar", "option_group_description", "Managed by Terraform"), - resource.TestCheckResourceAttr("aws_db_option_group.bar", "tags.%", "0"), + testAccCheckOptionGroupExists(resourceName, &v), + acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "rds", regexp.MustCompile(`og:.+`)), + resource.TestCheckResourceAttr(resourceName, "engine_name", "mysql"), + resource.TestCheckResourceAttr(resourceName, "major_engine_version", "8.0"), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "option.#", "0"), + resource.TestCheckResourceAttr(resourceName, "option_group_description", "Managed by Terraform"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"name_prefix"}, @@ -51,7 +52,8 @@ func TestAccRDSOptionGroup_basic(t *testing.T) { func TestAccRDSOptionGroup_timeoutBlock(t *testing.T) { var v rds.OptionGroup - rName := fmt.Sprintf("option-group-test-terraform-%s", sdkacctest.RandString(5)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -62,13 +64,12 @@ func TestAccRDSOptionGroup_timeoutBlock(t *testing.T) { { Config: testAccOptionGroupBasicTimeoutBlockConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), ), }, { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"name_prefix"}, @@ -90,8 +91,7 @@ func TestAccRDSOptionGroup_namePrefix(t *testing.T) { Config: testAccOptionGroup_namePrefix, Check: resource.ComposeTestCheckFunc( testAccCheckOptionGroupExists("aws_db_option_group.test", &v), - resource.TestMatchResourceAttr( - "aws_db_option_group.test", "name", regexp.MustCompile("^tf-test-")), + resource.TestMatchResourceAttr("aws_db_option_group.test", "name", regexp.MustCompile("^tf-test-")), ), }, { @@ -158,7 +158,8 @@ func TestAccRDSOptionGroup_optionGroupDescription(t *testing.T) { } func TestAccRDSOptionGroup_basicDestroyWithInstance(t *testing.T) { - rName := fmt.Sprintf("option-group-test-terraform-%s", sdkacctest.RandString(5)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -170,7 +171,7 @@ func TestAccRDSOptionGroup_basicDestroyWithInstance(t *testing.T) { Config: testAccOptionGroupBasicDestroyConfig(rName), }, { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"name_prefix"}, @@ -181,7 +182,8 @@ func TestAccRDSOptionGroup_basicDestroyWithInstance(t *testing.T) { func TestAccRDSOptionGroup_Option_optionSettings(t *testing.T) { var v rds.OptionGroup - rName := fmt.Sprintf("option-group-test-terraform-%s", sdkacctest.RandString(5)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -192,18 +194,16 @@ func TestAccRDSOptionGroup_Option_optionSettings(t *testing.T) { { Config: testAccOptionGroupOptionSettings(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "option.#", "1"), - resource.TestCheckTypeSetElemNestedAttrs("aws_db_option_group.bar", "option.*.option_settings.*", map[string]string{ + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "option.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "option.*.option_settings.*", map[string]string{ "value": "UTC", }), ), }, { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, // Ignore option since our current logic skips "unconfigured" default option settings @@ -213,19 +213,17 @@ func TestAccRDSOptionGroup_Option_optionSettings(t *testing.T) { { Config: testAccOptionGroupOptionSettings_update(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "option.#", "1"), - resource.TestCheckTypeSetElemNestedAttrs("aws_db_option_group.bar", "option.*.option_settings.*", map[string]string{ + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "option.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "option.*.option_settings.*", map[string]string{ "value": "US/Pacific", }), ), }, // Ensure we can import non-default value option settings { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"name_prefix"}, @@ -236,7 +234,8 @@ func TestAccRDSOptionGroup_Option_optionSettings(t *testing.T) { func TestAccRDSOptionGroup_OptionOptionSettings_iamRole(t *testing.T) { var v rds.OptionGroup - rName := fmt.Sprintf("option-group-test-terraform-%s", sdkacctest.RandString(5)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -247,16 +246,14 @@ func TestAccRDSOptionGroup_OptionOptionSettings_iamRole(t *testing.T) { { Config: testAccOptionGroupOptionSettingsIAMRole(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "option.#", "1"), + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "option.#", "1"), testAccCheckOptionGroupOptionSettingsIAMRole(&v), ), }, { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"name_prefix"}, @@ -267,7 +264,8 @@ func TestAccRDSOptionGroup_OptionOptionSettings_iamRole(t *testing.T) { func TestAccRDSOptionGroup_sqlServerOptionsUpdate(t *testing.T) { var v rds.OptionGroup - rName := fmt.Sprintf("option-group-test-terraform-%s", sdkacctest.RandString(5)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -278,13 +276,12 @@ func TestAccRDSOptionGroup_sqlServerOptionsUpdate(t *testing.T) { { Config: testAccOptionGroupSQLServerEEOptions(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), ), }, { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"name_prefix"}, @@ -292,11 +289,9 @@ func TestAccRDSOptionGroup_sqlServerOptionsUpdate(t *testing.T) { { Config: testAccOptionGroupSQLServerEEOptions_update(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "option.#", "1"), + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "option.#", "1"), ), }, }, @@ -305,7 +300,8 @@ func TestAccRDSOptionGroup_sqlServerOptionsUpdate(t *testing.T) { func TestAccRDSOptionGroup_oracleOptionsUpdate(t *testing.T) { var v rds.OptionGroup - rName := fmt.Sprintf("option-group-test-terraform-%s", sdkacctest.RandString(5)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -316,16 +312,14 @@ func TestAccRDSOptionGroup_oracleOptionsUpdate(t *testing.T) { { Config: testAccOptionGroupOracleEEOptionSettings(rName, "13.2.0.0.v2"), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "option.#", "1"), + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "option.#", "1"), testAccCheckOptionGroupOptionVersionAttribute(&v, "13.2.0.0.v2"), ), }, { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, // Ignore option since API responds with **** instead of password @@ -334,11 +328,9 @@ func TestAccRDSOptionGroup_oracleOptionsUpdate(t *testing.T) { { Config: testAccOptionGroupOracleEEOptionSettings(rName, "13.3.0.0.v2"), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "option.#", "1"), + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "option.#", "1"), testAccCheckOptionGroupOptionVersionAttribute(&v, "13.3.0.0.v2"), ), }, @@ -384,7 +376,8 @@ func TestAccRDSOptionGroup_OptionOptionSettings_multipleNonDefault(t *testing.T) func TestAccRDSOptionGroup_multipleOptions(t *testing.T) { var v rds.OptionGroup - rName := fmt.Sprintf("option-group-test-terraform-%s", sdkacctest.RandString(5)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_option_group.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -395,15 +388,13 @@ func TestAccRDSOptionGroup_multipleOptions(t *testing.T) { { Config: testAccOptionGroupMultipleOptions(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckOptionGroupExists("aws_db_option_group.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "name", rName), - resource.TestCheckResourceAttr( - "aws_db_option_group.bar", "option.#", "2"), + testAccCheckOptionGroupExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "option.#", "2"), ), }, { - ResourceName: "aws_db_option_group.bar", + ResourceName: resourceName, ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"name_prefix"}, @@ -613,38 +604,38 @@ func testAccCheckOptionGroupDestroy(s *terraform.State) error { return nil } -func testAccOptionGroupBasicTimeoutBlockConfig(r string) string { +func testAccOptionGroupBasicTimeoutBlockConfig(rName string) string { return fmt.Sprintf(` -resource "aws_db_option_group" "bar" { - name = "%s" +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform" engine_name = "mysql" - major_engine_version = "5.6" + major_engine_version = "8.0" timeouts { delete = "10m" } } -`, r) +`, rName) } -func testAccOptionGroupBasicConfig(r string) string { +func testAccOptionGroupBasicConfig(rName string) string { return fmt.Sprintf(` -resource "aws_db_option_group" "bar" { - name = "%s" +resource "aws_db_option_group" "test" { + name = %[1]q engine_name = "mysql" - major_engine_version = "5.6" + major_engine_version = "8.0" } -`, r) +`, rName) } -func testAccOptionGroupBasicDestroyConfig(r string) string { +func testAccOptionGroupBasicDestroyConfig(rName string) string { return fmt.Sprintf(` -resource "aws_db_instance" "bar" { +resource "aws_db_instance" "test" { allocated_storage = 10 - engine = "mysql" - engine_version = "5.6.35" - instance_class = "db.t2.micro" + engine = data.aws_rds_orderable_db_instance.test.engine + engine_version = data.aws_rds_orderable_db_instance.test.engine_version + instance_class = data.aws_rds_orderable_db_instance.test.instance_class name = "baz" password = "barbarbarbar" username = "foo" @@ -657,22 +648,31 @@ resource "aws_db_instance" "bar" { backup_retention_period = 0 skip_final_snapshot = true - option_group_name = aws_db_option_group.bar.name + option_group_name = aws_db_option_group.test.name } -resource "aws_db_option_group" "bar" { - name = "%s" +data "aws_rds_orderable_db_instance" "test" { + engine = "mysql" + license_model = "general-public-license" + storage_type = "standard" + + preferred_engine_versions = ["8.0.25", "8.0.26", "8.0.27"] + preferred_instance_classes = ["db.t2.micro", "db.t2.small", "db.t3.medium", "db.t3.large"] +} + +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform" engine_name = "mysql" - major_engine_version = "5.6" + major_engine_version = "8.0" } -`, r) +`, rName) } -func testAccOptionGroupOptionSettings(r string) string { +func testAccOptionGroupOptionSettings(rName string) string { return fmt.Sprintf(` -resource "aws_db_option_group" "bar" { - name = "%s" +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform" engine_name = "oracle-ee" major_engine_version = "12.2" @@ -686,10 +686,10 @@ resource "aws_db_option_group" "bar" { } } } -`, r) +`, rName) } -func testAccOptionGroupOptionSettingsIAMRole(r string) string { +func testAccOptionGroupOptionSettingsIAMRole(rName string) string { return fmt.Sprintf(` data "aws_partition" "current" {} @@ -709,8 +709,8 @@ resource "aws_iam_role" "sql_server_backup" { assume_role_policy = data.aws_iam_policy_document.rds_assume_role.json } -resource "aws_db_option_group" "bar" { - name = "%[1]s" +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform" engine_name = "sqlserver-ex" major_engine_version = "14.00" @@ -724,13 +724,13 @@ resource "aws_db_option_group" "bar" { } } } -`, r) +`, rName) } -func testAccOptionGroupOptionSettings_update(r string) string { +func testAccOptionGroupOptionSettings_update(rName string) string { return fmt.Sprintf(` -resource "aws_db_option_group" "bar" { - name = "%s" +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform" engine_name = "oracle-ee" major_engine_version = "12.2" @@ -744,24 +744,24 @@ resource "aws_db_option_group" "bar" { } } } -`, r) +`, rName) } -func testAccOptionGroupSQLServerEEOptions(r string) string { +func testAccOptionGroupSQLServerEEOptions(rName string) string { return fmt.Sprintf(` -resource "aws_db_option_group" "bar" { - name = "%s" +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform" engine_name = "sqlserver-ee" major_engine_version = "11.00" } -`, r) +`, rName) } -func testAccOptionGroupSQLServerEEOptions_update(r string) string { +func testAccOptionGroupSQLServerEEOptions_update(rName string) string { return fmt.Sprintf(` -resource "aws_db_option_group" "bar" { - name = "%s" +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform" engine_name = "sqlserver-ee" major_engine_version = "11.00" @@ -770,17 +770,17 @@ resource "aws_db_option_group" "bar" { option_name = "TDE" } } -`, r) +`, rName) } -func testAccOptionGroupOracleEEOptionSettings(r, optionVersion string) string { +func testAccOptionGroupOracleEEOptionSettings(rName, optionVersion string) string { return fmt.Sprintf(` resource "aws_security_group" "foo" { - name = "%[1]s" + name = %[1]q } -resource "aws_db_option_group" "bar" { - name = "%[1]s" +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform issue 748" engine_name = "oracle-ee" major_engine_version = "12.2" @@ -788,7 +788,7 @@ resource "aws_db_option_group" "bar" { option { option_name = "OEM_AGENT" port = "3872" - version = "%[2]s" + version = %[2]q vpc_security_group_memberships = [aws_security_group.foo.id] @@ -808,13 +808,13 @@ resource "aws_db_option_group" "bar" { } } } -`, r, optionVersion) +`, rName, optionVersion) } -func testAccOptionGroupMultipleOptions(r string) string { +func testAccOptionGroupMultipleOptions(rName string) string { return fmt.Sprintf(` -resource "aws_db_option_group" "bar" { - name = "%s" +resource "aws_db_option_group" "test" { + name = %[1]q option_group_description = "Test option group for terraform" engine_name = "oracle-ee" major_engine_version = "12.2" @@ -827,7 +827,7 @@ resource "aws_db_option_group" "bar" { option_name = "STATSPACK" } } -`, r) +`, rName) } const testAccOptionGroup_namePrefix = ` @@ -835,7 +835,7 @@ resource "aws_db_option_group" "test" { name_prefix = "tf-test-" option_group_description = "Test option group for terraform" engine_name = "mysql" - major_engine_version = "5.6" + major_engine_version = "8.0" } ` @@ -843,7 +843,7 @@ const testAccOptionGroup_generatedName = ` resource "aws_db_option_group" "test" { option_group_description = "Test option group for terraform" engine_name = "mysql" - major_engine_version = "5.6" + major_engine_version = "8.0" } ` @@ -851,9 +851,9 @@ func testAccOptionGroupOptionGroupDescriptionConfig(rName, optionGroupDescriptio return fmt.Sprintf(` resource "aws_db_option_group" "test" { engine_name = "mysql" - major_engine_version = "5.6" - name = %q - option_group_description = %q + major_engine_version = "8.0" + name = %[1]q + option_group_description = %[2]q } `, rName, optionGroupDescription) } @@ -862,15 +862,15 @@ func testAccOptionGroupOptionOptionSettingsMultipleConfig(rName, value string) s return fmt.Sprintf(` resource "aws_db_option_group" "test" { engine_name = "mysql" - major_engine_version = "5.6" - name = %q + major_engine_version = "8.0" + name = %[1]q option { option_name = "MARIADB_AUDIT_PLUGIN" option_settings { name = "SERVER_AUDIT_EXCL_USERS" - value = %q + value = %[2]q } option_settings { @@ -891,11 +891,11 @@ func testAccOptionGroupTags1Config(rName, tagKey1, tagValue1 string) string { return fmt.Sprintf(` resource "aws_db_option_group" "test" { engine_name = "mysql" - major_engine_version = "5.6" - name = %q + major_engine_version = "8.0" + name = %[1]q tags = { - %q = %q + %[2]q = %[3]q } } `, rName, tagKey1, tagValue1) @@ -905,12 +905,12 @@ func testAccOptionGroupTags2Config(rName, tagKey1, tagValue1, tagKey2, tagValue2 return fmt.Sprintf(` resource "aws_db_option_group" "test" { engine_name = "mysql" - major_engine_version = "5.6" - name = %q + major_engine_version = "8.0" + name = %[1]q tags = { - %q = %q - %q = %q + %[2]q = %[3]q + %[4]q = %[5]q } } `, rName, tagKey1, tagValue1, tagKey2, tagValue2) @@ -920,8 +920,8 @@ func testAccOptionGroupTagsWithOption1Config(rName, tagKey1, tagValue1 string) s return fmt.Sprintf(` resource "aws_db_option_group" "test" { engine_name = "mysql" - major_engine_version = "5.6" - name = %q + major_engine_version = "8.0" + name = %[1]q option { option_name = "MARIADB_AUDIT_PLUGIN" @@ -933,7 +933,7 @@ resource "aws_db_option_group" "test" { } tags = { - %q = %q + %[2]q = %[3]q } } `, rName, tagKey1, tagValue1) @@ -943,8 +943,8 @@ func testAccOptionGroupTagsWithOption2Config(rName, tagKey1, tagValue1, tagKey2, return fmt.Sprintf(` resource "aws_db_option_group" "test" { engine_name = "mysql" - major_engine_version = "5.6" - name = %q + major_engine_version = "8.0" + name = %[1]q option { option_name = "MARIADB_AUDIT_PLUGIN" @@ -956,8 +956,8 @@ resource "aws_db_option_group" "test" { } tags = { - %q = %q - %q = %q + %[2]q = %[3]q + %[4]q = %[5]q } } `, rName, tagKey1, tagValue1, tagKey2, tagValue2) From 8fd58b0b1c57add1b2fc932ea9ba27e67036b413 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Mar 2022 20:15:20 -0500 Subject: [PATCH 189/229] Add constants for instance classes --- internal/service/rds/consts.go | 75 +++++++++++++++++++++++++++++ internal/service/rds/consts_test.go | 12 +++++ 2 files changed, 87 insertions(+) create mode 100644 internal/service/rds/consts.go create mode 100644 internal/service/rds/consts_test.go diff --git a/internal/service/rds/consts.go b/internal/service/rds/consts.go new file mode 100644 index 00000000000..c31b4aa776e --- /dev/null +++ b/internal/service/rds/consts.go @@ -0,0 +1,75 @@ +package rds + +const ( + ClusterRoleStatusActive = "ACTIVE" + ClusterRoleStatusDeleted = "DELETED" + ClusterRoleStatusPending = "PENDING" +) + +const ( + StorageTypeStandard = "standard" + StorageTypeGp2 = "gp2" + StorageTypeIo1 = "io1" +) + +func StorageType_Values() []string { + return []string{ + StorageTypeStandard, + StorageTypeGp2, + StorageTypeIo1, + } +} + +// https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/accessing-monitoring.html#Overview.DBInstance.Status. +const ( + InstanceStatusAvailable = "available" + InstanceStatusBackingUp = "backing-up" + InstanceStatusConfiguringEnhancedMonitoring = "configuring-enhanced-monitoring" + InstanceStatusConfiguringLogExports = "configuring-log-exports" + InstanceStatusCreating = "creating" + InstanceStatusDeleting = "deleting" + InstanceStatusIncompatibleParameters = "incompatible-parameters" + InstanceStatusIncompatibleRestore = "incompatible-restore" + InstanceStatusModifying = "modifying" + InstanceStatusStarting = "starting" + InstanceStatusStopping = "stopping" + InstanceStatusStorageFull = "storage-full" + InstanceStatusStorageOptimization = "storage-optimization" +) + +const ( + EventSubscriptionStatusActive = "active" + EventSubscriptionStatusCreating = "creating" + EventSubscriptionStatusDeleting = "deleting" + EventSubscriptionStatusModifying = "modifying" +) + +const ( + ExportableLogTypeAgent = "agent" + ExportableLogTypeAlert = "alert" + ExportableLogTypeAudit = "audit" + ExportableLogTypeError = "error" + ExportableLogTypeGeneral = "general" + ExportableLogTypeListener = "listener" + ExportableLogTypeOEMAgent = "oemagent" + ExportableLogTypePostgreSQL = "postgresql" + ExportableLogTypeSlowQuery = "slowquery" + ExportableLogTypeTrace = "trace" + ExportableLogTypeUpgrade = "upgrade" +) + +func ExportableLogType_Values() []string { + return []string{ + ExportableLogTypeAgent, + ExportableLogTypeAlert, + ExportableLogTypeAudit, + ExportableLogTypeError, + ExportableLogTypeGeneral, + ExportableLogTypeListener, + ExportableLogTypeOEMAgent, + ExportableLogTypePostgreSQL, + ExportableLogTypeSlowQuery, + ExportableLogTypeTrace, + ExportableLogTypeUpgrade, + } +} diff --git a/internal/service/rds/consts_test.go b/internal/service/rds/consts_test.go new file mode 100644 index 00000000000..b2e22376478 --- /dev/null +++ b/internal/service/rds/consts_test.go @@ -0,0 +1,12 @@ +package rds_test + +const ( + // Please make sure GovCloud and commercial support these since they vary + postgresPreferredInstanceClasses = `"db.t3.micro", "db.t3.small", "db.t2.small", "db.t2.medium"` + mySQLPreferredInstanceClasses = `"db.t3.micro", "db.t3.small", "db.t2.small", "db.t2.medium"` + mariaDBPreferredInstanceClasses = `"db.t3.micro", "db.t3.small", "db.t2.small", "db.t2.medium"` + oraclePreferredInstanceClasses = `"db.t3.medium", "db.t2.medium", "db.t3.large", "db.t2.large"` // Oracle requires at least a medium instance as a replica source + sqlServerPreferredInstanceClasses = `"db.t2.small", "db.t3.small"` + sqlServerSEPreferredInstanceClasses = `"db.m5.large", "db.m4.large", "db.r4.large"` + oracleSE2PreferredInstanceClasses = `"db.m5.large", "db.m4.large", "db.r4.large"` +) From 44832e1a350cd0a657d6b9b919a84259f6d307da Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Mar 2022 20:15:49 -0500 Subject: [PATCH 190/229] rds/cluster: Debugging --- internal/service/rds/cluster.go | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/internal/service/rds/cluster.go b/internal/service/rds/cluster.go index d7d9e5874f2..31391e56678 100644 --- a/internal/service/rds/cluster.go +++ b/internal/service/rds/cluster.go @@ -23,9 +23,9 @@ import ( ) const ( - rdsClusterScalingConfiguration_DefaultMinCapacity = 1 - rdsClusterScalingConfiguration_DefaultMaxCapacity = 16 - rdsClusterTimeoutDelete = 2 * time.Minute + clusterScalingConfiguration_DefaultMinCapacity = 1 + clusterScalingConfiguration_DefaultMaxCapacity = 16 + clusterTimeoutDelete = 2 * time.Minute ) func ResourceCluster() *schema.Resource { @@ -205,12 +205,12 @@ func ResourceCluster() *schema.Resource { "max_capacity": { Type: schema.TypeInt, Optional: true, - Default: rdsClusterScalingConfiguration_DefaultMaxCapacity, + Default: clusterScalingConfiguration_DefaultMaxCapacity, }, "min_capacity": { Type: schema.TypeInt, Optional: true, - Default: rdsClusterScalingConfiguration_DefaultMinCapacity, + Default: clusterScalingConfiguration_DefaultMinCapacity, }, "seconds_until_auto_pause": { Type: schema.TypeInt, @@ -1084,7 +1084,7 @@ func resourceClusterRead(d *schema.ResourceData, meta interface{}) error { d.Set("hosted_zone_id", dbc.HostedZoneId) d.Set("iam_database_authentication_enabled", dbc.IAMDatabaseAuthenticationEnabled) - rdsClusterSetResourceDataEngineVersionFromCluster(d, dbc) + clusterSetResourceDataEngineVersionFromCluster(d, dbc) var roles []string for _, r := range dbc.AssociatedRoles { @@ -1401,7 +1401,7 @@ func resourceClusterDelete(d *schema.ResourceData, meta interface{}) error { log.Printf("[DEBUG] RDS Cluster delete options: %s", deleteOpts) - err := resource.Retry(rdsClusterTimeoutDelete, func() *resource.RetryError { + err := resource.Retry(clusterTimeoutDelete, func() *resource.RetryError { _, err := conn.DeleteDBCluster(&deleteOpts) if err != nil { if tfawserr.ErrMessageContains(err, rds.ErrCodeInvalidDBClusterStateFault, "is not currently in the available state") { @@ -1538,25 +1538,8 @@ func WaitForClusterDeletion(conn *rds.RDS, id string, timeout time.Duration) err return err } -func rdsClusterSetResourceDataEngineVersionFromCluster(d *schema.ResourceData, c *rds.DBCluster) { +func clusterSetResourceDataEngineVersionFromCluster(d *schema.ResourceData, c *rds.DBCluster) { oldVersion := d.Get("engine_version").(string) newVersion := aws.StringValue(c.EngineVersion) compareActualEngineVersion(d, oldVersion, newVersion) } - -func compareActualEngineVersion(d *schema.ResourceData, oldVersion string, newVersion string) { - newVersionSubstr := newVersion - - if len(newVersion) > len(oldVersion) { - newVersionSubstr = string([]byte(newVersion)[0 : len(oldVersion)+1]) - } - - if oldVersion != newVersion && string(append([]byte(oldVersion), []byte(".")...)) != newVersionSubstr { - d.Set("engine_version", newVersion) - fmt.Printf("[READ/cluster] engine_version: %s\n", newVersion) - } - - d.Set("engine_version_actual", newVersion) - fmt.Printf("[READ/cluster] engine_version_actual: %s\n", newVersion) - -} From bbf84038e3793df52f7d44ab65ea40f8cdd0dbdc Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Mar 2022 20:16:16 -0500 Subject: [PATCH 191/229] rds/instance: Modernize tests --- internal/service/rds/instance_test.go | 696 +++++++++++++------------- 1 file changed, 349 insertions(+), 347 deletions(-) diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index 63610423e33..7c3ac2a553f 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -173,7 +173,7 @@ func TestAccRDSInstance_onlyMajorVersion(t *testing.T) { CheckDestroy: testAccCheckClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_MajorVersionOnly(engine, engineVersion), + Config: testAccInstanceConfig_MajorVersionOnly(), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &dbInstance1), resource.TestCheckResourceAttr(resourceName, "engine", engine), @@ -260,6 +260,7 @@ func TestAccRDSInstance_kmsKey(t *testing.T) { var v rds.DBInstance kmsKeyResourceName := "aws_kms_key.foo" resourceName := "aws_db_instance.bar" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -268,7 +269,7 @@ func TestAccRDSInstance_kmsKey(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_KMSKeyID(sdkacctest.RandInt()), + Config: testAccInstanceConfig_KMSKeyID(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &v), testAccCheckInstanceAttributes(&v), @@ -293,7 +294,7 @@ func TestAccRDSInstance_kmsKey(t *testing.T) { func TestAccRDSInstance_subnetGroup(t *testing.T) { var v rds.DBInstance - rName := sdkacctest.RandString(10) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -324,7 +325,7 @@ func TestAccRDSInstance_subnetGroup(t *testing.T) { func TestAccRDSInstance_optionGroup(t *testing.T) { var v rds.DBInstance - rName := fmt.Sprintf("tf-option-test-%d", sdkacctest.RandInt()) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -347,6 +348,7 @@ func TestAccRDSInstance_optionGroup(t *testing.T) { func TestAccRDSInstance_iamAuth(t *testing.T) { var v rds.DBInstance + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -355,7 +357,7 @@ func TestAccRDSInstance_iamAuth(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_IAMAuth(sdkacctest.RandInt()), + Config: testAccInstanceConfig_IAMAuth(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_db_instance.bar", &v), testAccCheckInstanceAttributes(&v), @@ -536,7 +538,7 @@ func TestAccRDSInstance_deletionProtection(t *testing.T) { func TestAccRDSInstance_finalSnapshotIdentifier(t *testing.T) { var snap rds.DBInstance - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -547,7 +549,7 @@ func TestAccRDSInstance_finalSnapshotIdentifier(t *testing.T) { CheckDestroy: testAccCheckInstanceSnapshot, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_FinalSnapshotIdentifier(rInt), + Config: testAccInstanceConfig_FinalSnapshotIdentifier(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_db_instance.snapshot", &snap), ), @@ -558,6 +560,7 @@ func TestAccRDSInstance_finalSnapshotIdentifier(t *testing.T) { func TestAccRDSInstance_FinalSnapshotIdentifier_skipFinalSnapshot(t *testing.T) { var snap rds.DBInstance + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -566,7 +569,7 @@ func TestAccRDSInstance_FinalSnapshotIdentifier_skipFinalSnapshot(t *testing.T) CheckDestroy: testAccCheckInstanceNoSnapshot, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_FinalSnapshotIdentifier_SkipFinalSnapshot(), + Config: testAccInstanceConfig_FinalSnapshotIdentifier_SkipFinalSnapshot(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_db_instance.snapshot", &snap), ), @@ -1571,8 +1574,7 @@ func TestAccRDSInstance_ReplicateSourceDB_parameterGroupTwoStep(t *testing.T) { func TestAccRDSInstance_s3Import_basic(t *testing.T) { var snap rds.DBInstance - bucket := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - uniqueId := sdkacctest.RandomWithPrefix("tf-acc-s3-import-test") + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) bucketPrefix := sdkacctest.RandString(5) const resourceName = "aws_db_instance.test" @@ -1584,10 +1586,10 @@ func TestAccRDSInstance_s3Import_basic(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_S3Import_basic(bucket, bucketPrefix, uniqueId), + Config: testAccInstanceConfig_S3Import_basic(rName, bucketPrefix), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &snap), - resource.TestCheckResourceAttr(resourceName, "identifier", uniqueId), + resource.TestCheckResourceAttr(resourceName, "identifier", rName), resource.TestCheckResourceAttr(resourceName, "identifier_prefix", ""), ), }, @@ -1605,8 +1607,7 @@ func TestAccRDSInstance_s3Import_basic(t *testing.T) { func TestAccRDSInstance_s3Import_NameDeprecated_basic(t *testing.T) { var snap rds.DBInstance - bucket := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - uniqueId := sdkacctest.RandomWithPrefix("tf-acc-s3-import-test") + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) bucketPrefix := sdkacctest.RandString(5) const resourceName = "aws_db_instance.test" @@ -1618,10 +1619,10 @@ func TestAccRDSInstance_s3Import_NameDeprecated_basic(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_S3Import_NameDeprecated_basic(bucket, bucketPrefix, uniqueId), + Config: testAccInstanceConfig_S3Import_NameDeprecated_basic(rName, bucketPrefix), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &snap), - resource.TestCheckResourceAttr(resourceName, "identifier", uniqueId), + resource.TestCheckResourceAttr(resourceName, "identifier", rName), resource.TestCheckResourceAttr(resourceName, "identifier_prefix", ""), ), }, @@ -1640,7 +1641,7 @@ func TestAccRDSInstance_s3Import_NameDeprecated_basic(t *testing.T) { func TestAccRDSInstance_s3Import_namePrefix(t *testing.T) { var snap rds.DBInstance const identifierPrefix = "tf-acc-test-prefix-" - bucket := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) bucketPrefix := sdkacctest.RandString(5) const resourceName = "aws_db_instance.test" @@ -1652,7 +1653,7 @@ func TestAccRDSInstance_s3Import_namePrefix(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_S3Import_namePrefix(bucket, bucketPrefix, identifierPrefix), + Config: testAccInstanceConfig_S3Import_namePrefix(rName, bucketPrefix, identifierPrefix), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &snap), create.TestCheckResourceAttrNameFromPrefix(resourceName, "identifier", identifierPrefix), @@ -1673,7 +1674,7 @@ func TestAccRDSInstance_s3Import_namePrefix(t *testing.T) { func TestAccRDSInstance_s3Import_nameGenerated(t *testing.T) { var snap rds.DBInstance - bucket := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) bucketPrefix := sdkacctest.RandString(5) const resourceName = "aws_db_instance.test" @@ -1685,7 +1686,7 @@ func TestAccRDSInstance_s3Import_nameGenerated(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_S3Import_nameGenerated(bucket, bucketPrefix), + Config: testAccInstanceConfig_S3Import_nameGenerated(rName, bucketPrefix), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &snap), create.TestCheckResourceAttrNameGenerated(resourceName, "identifier"), @@ -2729,7 +2730,7 @@ func TestAccRDSInstance_MonitoringRoleARN_removedToEnabled(t *testing.T) { func TestAccRDSInstance_separateIopsUpdate(t *testing.T) { var v rds.DBInstance - rName := sdkacctest.RandString(5) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2759,7 +2760,7 @@ func TestAccRDSInstance_separateIopsUpdate(t *testing.T) { func TestAccRDSInstance_portUpdate(t *testing.T) { var v rds.DBInstance - rName := sdkacctest.RandString(5) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2768,7 +2769,7 @@ func TestAccRDSInstance_portUpdate(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_SnapshotInstanceConfig_mysqlPort(rName), + Config: testAccInstanceConfig_SnapshotInstanceConfig_mySQLPort(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_db_instance.bar", &v), resource.TestCheckResourceAttr( @@ -2790,7 +2791,8 @@ func TestAccRDSInstance_portUpdate(t *testing.T) { func TestAccRDSInstance_MSSQL_tz(t *testing.T) { var v rds.DBInstance - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2799,26 +2801,22 @@ func TestAccRDSInstance_MSSQL_tz(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_MSSQL_timezone(rInt), + Config: testAccInstanceConfig_MSSQL_timezone(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists("aws_db_instance.mssql", &v), + testAccCheckInstanceExists(resourceName, &v), testAccCheckInstanceAttributes_MSSQL(&v, ""), - resource.TestCheckResourceAttr( - "aws_db_instance.mssql", "allocated_storage", "20"), - resource.TestCheckResourceAttr( - "aws_db_instance.mssql", "engine", "sqlserver-ex"), + resource.TestCheckResourceAttr(resourceName, "allocated_storage", "20"), + resource.TestCheckResourceAttr(resourceName, "engine", "sqlserver-ex"), ), }, { - Config: testAccInstanceConfig_MSSQL_timezone_AKST(rInt), + Config: testAccInstanceConfig_MSSQL_timezone_AKST(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists("aws_db_instance.mssql", &v), + testAccCheckInstanceExists(resourceName, &v), testAccCheckInstanceAttributes_MSSQL(&v, "Alaskan Standard Time"), - resource.TestCheckResourceAttr( - "aws_db_instance.mssql", "allocated_storage", "20"), - resource.TestCheckResourceAttr( - "aws_db_instance.mssql", "engine", "sqlserver-ex"), + resource.TestCheckResourceAttr(resourceName, "allocated_storage", "20"), + resource.TestCheckResourceAttr(resourceName, "engine", "sqlserver-ex"), ), }, }, @@ -2892,7 +2890,7 @@ func TestAccRDSInstance_MSSQL_domainSnapshotRestore(t *testing.T) { func TestAccRDSInstance_MySQL_snapshotRestoreWithEngineVersion(t *testing.T) { var v, vRestoredInstance rds.DBInstance - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2901,7 +2899,7 @@ func TestAccRDSInstance_MySQL_snapshotRestoreWithEngineVersion(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_MySQLSnapshotRestoreWithEngineVersion(rInt), + Config: testAccInstanceConfig_MySQLSnapshotRestoreWithEngineVersion(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_db_instance.mysql_restore", &vRestoredInstance), testAccCheckInstanceExists("aws_db_instance.mysql", &v), @@ -2915,6 +2913,7 @@ func TestAccRDSInstance_MySQL_snapshotRestoreWithEngineVersion(t *testing.T) { func TestAccRDSInstance_minorVersion(t *testing.T) { var v rds.DBInstance + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2923,7 +2922,7 @@ func TestAccRDSInstance_minorVersion(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_AutoMinorVersion(), + Config: testAccInstanceConfig_AutoMinorVersion(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_db_instance.bar", &v), ), @@ -2934,7 +2933,7 @@ func TestAccRDSInstance_minorVersion(t *testing.T) { func TestAccRDSInstance_ec2Classic(t *testing.T) { var v rds.DBInstance - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_instance.bar" resource.ParallelTest(t, resource.TestCase{ @@ -2944,7 +2943,7 @@ func TestAccRDSInstance_ec2Classic(t *testing.T) { CheckDestroy: testAccCheckInstanceEC2ClassicDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_EC2Classic(rInt), + Config: testAccInstanceConfig_EC2Classic(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceEC2ClassicExists(resourceName, &v), ), @@ -2956,7 +2955,7 @@ func TestAccRDSInstance_ec2Classic(t *testing.T) { func TestAccRDSInstance_cloudWatchLogsExport(t *testing.T) { var v rds.DBInstance - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2965,7 +2964,7 @@ func TestAccRDSInstance_cloudWatchLogsExport(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_CloudWatchLogsExportConfiguration(rInt), + Config: testAccInstanceConfig_CloudWatchLogsExportConfiguration(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists("aws_db_instance.bar", &v), ), @@ -2989,7 +2988,7 @@ func TestAccRDSInstance_cloudWatchLogsExport(t *testing.T) { func TestAccRDSInstance_EnabledCloudWatchLogsExports_mySQL(t *testing.T) { var v rds.DBInstance resourceName := "aws_db_instance.bar" - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2998,7 +2997,7 @@ func TestAccRDSInstance_EnabledCloudWatchLogsExports_mySQL(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_CloudWatchLogsExportConfiguration(rInt), + Config: testAccInstanceConfig_CloudWatchLogsExportConfiguration(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &v), resource.TestCheckResourceAttr(resourceName, "enabled_cloudwatch_logs_exports.#", "2"), @@ -3007,7 +3006,7 @@ func TestAccRDSInstance_EnabledCloudWatchLogsExports_mySQL(t *testing.T) { ), }, { - Config: testAccInstanceConfig_CloudWatchLogsExportConfigurationAdd(rInt), + Config: testAccInstanceConfig_CloudWatchLogsExportConfigurationAdd(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &v), resource.TestCheckResourceAttr(resourceName, "enabled_cloudwatch_logs_exports.#", "3"), @@ -3017,7 +3016,7 @@ func TestAccRDSInstance_EnabledCloudWatchLogsExports_mySQL(t *testing.T) { ), }, { - Config: testAccInstanceConfig_CloudWatchLogsExportConfigurationModify(rInt), + Config: testAccInstanceConfig_CloudWatchLogsExportConfigurationModify(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &v), resource.TestCheckResourceAttr(resourceName, "enabled_cloudwatch_logs_exports.#", "3"), @@ -3027,7 +3026,7 @@ func TestAccRDSInstance_EnabledCloudWatchLogsExports_mySQL(t *testing.T) { ), }, { - Config: testAccInstanceConfig_CloudWatchLogsExportConfigurationDelete(rInt), + Config: testAccInstanceConfig_CloudWatchLogsExportConfigurationDelete(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(resourceName, &v), resource.TestCheckResourceAttr(resourceName, "enabled_cloudwatch_logs_exports.#", "0"), @@ -3144,7 +3143,7 @@ func TestAccRDSInstance_EnabledCloudWatchLogsExports_postgresql(t *testing.T) { func TestAccRDSInstance_noDeleteAutomatedBackups(t *testing.T) { var dbInstance rds.DBInstance - rName := sdkacctest.RandomWithPrefix("tf-testacc-nodelautobak") + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_instance.test" resource.ParallelTest(t, resource.TestCase{ @@ -3749,6 +3748,7 @@ func TestAccRDSInstance_RestoreToPointInTime_sourceIdentifier(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance sourceName := "aws_db_instance.test" resourceName := "aws_db_instance.restore" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -3757,7 +3757,7 @@ func TestAccRDSInstance_RestoreToPointInTime_sourceIdentifier(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_RestoreToPointInTime_SourceIdentifier(), + Config: testAccInstanceConfig_RestoreToPointInTime_SourceIdentifier(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(sourceName, &sourceDbInstance), testAccCheckInstanceExists(resourceName, &dbInstance), @@ -3785,6 +3785,7 @@ func TestAccRDSInstance_RestoreToPointInTime_sourceResourceID(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance sourceName := "aws_db_instance.test" resourceName := "aws_db_instance.restore" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -3793,7 +3794,7 @@ func TestAccRDSInstance_RestoreToPointInTime_sourceResourceID(t *testing.T) { CheckDestroy: testAccCheckInstanceDestroy, Steps: []resource.TestStep{ { - Config: testAccInstanceConfig_RestoreToPointInTime_SourceResourceID(), + Config: testAccInstanceConfig_RestoreToPointInTime_SourceResourceID(rName), Check: resource.ComposeTestCheckFunc( testAccCheckInstanceExists(sourceName, &sourceDbInstance), testAccCheckInstanceExists(resourceName, &dbInstance), @@ -4096,54 +4097,38 @@ func TestAccRDSInstance_license(t *testing.T) { }) } -func testAccInstanceConfig_orderableClass(engine, version, license string) string { +func testAccInstanceConfig_orderableClass(engine, license, storage, classes string) string { return fmt.Sprintf(` -data "aws_rds_orderable_db_instance" "test" { - engine = %[1]q - engine_version = %[2]q - license_model = %[3]q - storage_type = "standard" - - preferred_instance_classes = ["db.t3.micro", "db.t2.micro", "db.t2.medium"] -} -`, engine, version, license) +data "aws_rds_engine_version" "default" { + engine = %[1]q } -func testAccInstanceConfig_orderableClass_SQLServerEx(engine, version, license string) string { - return fmt.Sprintf(` data "aws_rds_orderable_db_instance" "test" { - engine = %[1]q - engine_version = %[2]q - license_model = %[3]q - storage_type = "standard" + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + license_model = %[2]q + storage_type = %[3]q - preferred_instance_classes = ["db.t2.small", "db.t3.small"] + preferred_instance_classes = [%[4]s] } -`, engine, version, license) +`, engine, license, storage, classes) } func testAccInstanceConfig_orderableClassMySQL() string { - return testAccInstanceConfig_orderableClass("mysql", "8.0.23", "general-public-license") + return testAccInstanceConfig_orderableClass("mysql", "general-public-license", "standard", mySQLPreferredInstanceClasses) } func testAccInstanceConfig_orderableClassMariadb() string { - return testAccInstanceConfig_orderableClass("mariadb", "10.5.12", "general-public-license") + return testAccInstanceConfig_orderableClass("mariadb", "general-public-license", "standard", mariaDBPreferredInstanceClasses) } func testAccInstanceConfig_orderableClassSQLServerEx() string { - return testAccInstanceConfig_orderableClass_SQLServerEx("sqlserver-ex", "15.00.4073.23.v1", "license-included") + return testAccInstanceConfig_orderableClass("sqlserver-ex", "license-included", "standard", sqlServerPreferredInstanceClasses) } -const testAccInstanceConfig_orderableClassSQLServerSe = ` -data "aws_rds_orderable_db_instance" "test" { - engine = "sqlserver-se" - engine_version = "15.00.4073.23.v1" - license_model = "license-included" - storage_type = "standard" - - preferred_instance_classes = ["db.m5.large", "db.m4.large", "db.r4.large"] +func testAccInstanceConfig_orderableClassSQLServerSe() string { + return testAccInstanceConfig_orderableClass("sqlserver-se", "license-included", "standard", sqlServerSEPreferredInstanceClasses) } -` func testAccInstanceBasicConfig(rName string) string { return acctest.ConfigCompose( @@ -4156,8 +4141,8 @@ resource "aws_db_instance" "test" { engine = data.aws_rds_orderable_db_instance.test.engine engine_version = data.aws_rds_orderable_db_instance.test.engine_version instance_class = data.aws_rds_orderable_db_instance.test.instance_class - name = "baz" - parameter_group_name = "default.mysql8.0" + db_name = "baz" + parameter_group_name = "default.${data.aws_rds_engine_version.default.parameter_group_family}" password = "barbarbarbar" skip_final_snapshot = true username = "test" @@ -4182,7 +4167,7 @@ resource "aws_db_instance" "test" { engine_version = data.aws_rds_orderable_db_instance.test.engine_version instance_class = data.aws_rds_orderable_db_instance.test.instance_class name = "baz" # deprecated - parameter_group_name = "default.mysql8.0" + parameter_group_name = "default.${data.aws_rds_engine_version.default.parameter_group_family}" password = "barbarbarbar" skip_final_snapshot = true username = "test" @@ -4195,18 +4180,18 @@ resource "aws_db_instance" "test" { `, rName)) } -func testAccInstanceConfig_MajorVersionOnly(engine, engineVersion string) string { +func testAccInstanceConfig_MajorVersionOnly() string { return acctest.ConfigCompose( testAccInstanceConfig_orderableClassMySQL(), fmt.Sprintf(` resource "aws_db_instance" "test" { allocated_storage = 10 backup_retention_period = 0 - engine = data.aws_rds_orderable_db_instance.test.engine - engine_version = %[1]q + engine = data.aws_rds_engine_version.default.engine + engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) instance_class = data.aws_rds_orderable_db_instance.test.instance_class - name = "baz" - parameter_group_name = "default.%[2]s%[1]s" + db_name = "baz" + parameter_group_name = "default.${data.aws_rds_engine_version.default.parameter_group_family}" password = "barbarbarbar" skip_final_snapshot = true username = "foo" @@ -4216,7 +4201,7 @@ resource "aws_db_instance" "test" { # validation error). maintenance_window = "Fri:09:00-Fri:09:30" } -`, engineVersion, engine)) +`)) } func testAccInstanceConfig_namePrefix(identifierPrefix string) string { @@ -4251,10 +4236,10 @@ resource "aws_db_instance" "test" { `) } -func testAccInstanceConfig_KMSKeyID(rInt int) string { +func testAccInstanceConfig_KMSKeyID(rName string) string { return fmt.Sprintf(` resource "aws_kms_key" "foo" { - description = "Terraform acc test %d" + description = %[1]q policy = < Date: Mon, 7 Mar 2022 20:16:48 -0500 Subject: [PATCH 192/229] rds/option_group_test: Make version dynamic --- internal/service/rds/option_group_test.go | 163 +++++++++++++++------- 1 file changed, 116 insertions(+), 47 deletions(-) diff --git a/internal/service/rds/option_group_test.go b/internal/service/rds/option_group_test.go index 1789e519b32..658c29d44b3 100644 --- a/internal/service/rds/option_group_test.go +++ b/internal/service/rds/option_group_test.go @@ -606,11 +606,15 @@ func testAccCheckOptionGroupDestroy(s *terraform.State) error { func testAccOptionGroupBasicTimeoutBlockConfig(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { name = %[1]q option_group_description = "Test option group for terraform" - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) timeouts { delete = "10m" @@ -621,16 +625,30 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupBasicConfig(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { name = %[1]q - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) } `, rName) } func testAccOptionGroupBasicDestroyConfig(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + +data "aws_rds_orderable_db_instance" "test" { + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + preferred_instance_classes = [%[1]s] +} + resource "aws_db_instance" "test" { allocated_storage = 10 engine = data.aws_rds_orderable_db_instance.test.engine @@ -651,31 +669,26 @@ resource "aws_db_instance" "test" { option_group_name = aws_db_option_group.test.name } -data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" - license_model = "general-public-license" - storage_type = "standard" - - preferred_engine_versions = ["8.0.25", "8.0.26", "8.0.27"] - preferred_instance_classes = ["db.t2.micro", "db.t2.small", "db.t3.medium", "db.t3.large"] -} - resource "aws_db_option_group" "test" { - name = %[1]q + name = %[2]q option_group_description = "Test option group for terraform" - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) } -`, rName) +`, mySQLPreferredInstanceClasses, rName) } func testAccOptionGroupOptionSettings(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "oracle-ee" +} + resource "aws_db_option_group" "test" { name = %[1]q option_group_description = "Test option group for terraform" - engine_name = "oracle-ee" - major_engine_version = "12.2" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+", data.aws_rds_engine_version.default.version) option { option_name = "Timezone" @@ -693,6 +706,10 @@ func testAccOptionGroupOptionSettingsIAMRole(rName string) string { return fmt.Sprintf(` data "aws_partition" "current" {} +data "aws_rds_engine_version" "default" { + engine = "sqlserver-ex" +} + data "aws_iam_policy_document" "rds_assume_role" { statement { actions = ["sts:AssumeRole"] @@ -712,8 +729,8 @@ resource "aws_iam_role" "sql_server_backup" { resource "aws_db_option_group" "test" { name = %[1]q option_group_description = "Test option group for terraform" - engine_name = "sqlserver-ex" - major_engine_version = "14.00" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) option { option_name = "SQLSERVER_BACKUP_RESTORE" @@ -729,11 +746,15 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupOptionSettings_update(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "oracle-ee" +} + resource "aws_db_option_group" "test" { name = %[1]q option_group_description = "Test option group for terraform" - engine_name = "oracle-ee" - major_engine_version = "12.2" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+", data.aws_rds_engine_version.default.version) option { option_name = "Timezone" @@ -749,22 +770,30 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupSQLServerEEOptions(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "sqlserver-ee" +} + resource "aws_db_option_group" "test" { name = %[1]q option_group_description = "Test option group for terraform" - engine_name = "sqlserver-ee" - major_engine_version = "11.00" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) } `, rName) } func testAccOptionGroupSQLServerEEOptions_update(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "sqlserver-ee" +} + resource "aws_db_option_group" "test" { name = %[1]q option_group_description = "Test option group for terraform" - engine_name = "sqlserver-ee" - major_engine_version = "11.00" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) option { option_name = "TDE" @@ -775,6 +804,10 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupOracleEEOptionSettings(rName, optionVersion string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "oracle-ee" +} + resource "aws_security_group" "foo" { name = %[1]q } @@ -782,8 +815,8 @@ resource "aws_security_group" "foo" { resource "aws_db_option_group" "test" { name = %[1]q option_group_description = "Test option group for terraform issue 748" - engine_name = "oracle-ee" - major_engine_version = "12.2" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+", data.aws_rds_engine_version.default.version) option { option_name = "OEM_AGENT" @@ -813,11 +846,15 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupMultipleOptions(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "oracle-ee" +} + resource "aws_db_option_group" "test" { name = %[1]q option_group_description = "Test option group for terraform" - engine_name = "oracle-ee" - major_engine_version = "12.2" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+", data.aws_rds_engine_version.default.version) option { option_name = "SPATIAL" @@ -831,27 +868,39 @@ resource "aws_db_option_group" "test" { } const testAccOptionGroup_namePrefix = ` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { name_prefix = "tf-test-" option_group_description = "Test option group for terraform" - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) } ` const testAccOptionGroup_generatedName = ` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { option_group_description = "Test option group for terraform" - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) } ` func testAccOptionGroupOptionGroupDescriptionConfig(rName, optionGroupDescription string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) name = %[1]q option_group_description = %[2]q } @@ -860,9 +909,13 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupOptionOptionSettingsMultipleConfig(rName, value string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) name = %[1]q option { @@ -889,9 +942,13 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupTags1Config(rName, tagKey1, tagValue1 string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) name = %[1]q tags = { @@ -903,9 +960,13 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupTags2Config(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) name = %[1]q tags = { @@ -918,9 +979,13 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupTagsWithOption1Config(rName, tagKey1, tagValue1 string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) name = %[1]q option { @@ -941,9 +1006,13 @@ resource "aws_db_option_group" "test" { func testAccOptionGroupTagsWithOption2Config(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + resource "aws_db_option_group" "test" { - engine_name = "mysql" - major_engine_version = "8.0" + engine_name = data.aws_rds_engine_version.default.engine + major_engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) name = %[1]q option { From cfe8c7f26436b68b27d6ea995214855d8bf1db05 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Mar 2022 20:17:20 -0500 Subject: [PATCH 193/229] rds/ds/orderable: Make version dynamic --- .../orderable_instance_data_source_test.go | 189 +++++++++++------- 1 file changed, 120 insertions(+), 69 deletions(-) diff --git a/internal/service/rds/orderable_instance_data_source_test.go b/internal/service/rds/orderable_instance_data_source_test.go index c767a674a51..586dea7dd56 100644 --- a/internal/service/rds/orderable_instance_data_source_test.go +++ b/internal/service/rds/orderable_instance_data_source_test.go @@ -13,9 +13,7 @@ import ( func TestAccRDSOrderableInstanceDataSource_basic(t *testing.T) { dataSourceName := "data.aws_rds_orderable_db_instance.test" - class := "db.t2.small" engine := "mysql" - engineVersion := "5.7.22" licenseModel := "general-public-license" storageType := "standard" @@ -26,13 +24,13 @@ func TestAccRDSOrderableInstanceDataSource_basic(t *testing.T) { CheckDestroy: nil, Steps: []resource.TestStep{ { - Config: testAccOrderableInstanceDataSourceConfig_basic(class, engine, engineVersion, licenseModel, storageType), + Config: testAccOrderableInstanceDataSourceConfig_basic(engine, licenseModel, storageType), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "instance_class", class), resource.TestCheckResourceAttr(dataSourceName, "engine", engine), - resource.TestCheckResourceAttr(dataSourceName, "engine_version", engineVersion), resource.TestCheckResourceAttr(dataSourceName, "license_model", licenseModel), resource.TestCheckResourceAttr(dataSourceName, "storage_type", storageType), + resource.TestCheckResourceAttrPair(dataSourceName, "engine_version", "data.aws_rds_engine_version.default", "version"), + resource.TestCheckResourceAttrPair(dataSourceName, "instance_class", "data.aws_rds_orderable_db_instance.dynamic", "instance_class"), ), }, }, @@ -41,7 +39,7 @@ func TestAccRDSOrderableInstanceDataSource_basic(t *testing.T) { func TestAccRDSOrderableInstanceDataSource_preferredClass(t *testing.T) { dataSourceName := "data.aws_rds_orderable_db_instance.test" - preferredClass := "db.t2.micro" + preferredClass := "db.t3.micro" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccOrderableInstancePreCheck(t) }, @@ -61,7 +59,6 @@ func TestAccRDSOrderableInstanceDataSource_preferredClass(t *testing.T) { func TestAccRDSOrderableInstanceDataSource_preferredVersion(t *testing.T) { dataSourceName := "data.aws_rds_orderable_db_instance.test" - preferredVersion := "5.7.22" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccOrderableInstancePreCheck(t) }, @@ -70,9 +67,9 @@ func TestAccRDSOrderableInstanceDataSource_preferredVersion(t *testing.T) { CheckDestroy: nil, Steps: []resource.TestStep{ { - Config: testAccOrderableInstanceDataSourceConfig_preferredVersion(preferredVersion), + Config: testAccOrderableInstanceDataSourceConfig_preferredVersion(), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "engine_version", preferredVersion), + resource.TestCheckResourceAttrPair(dataSourceName, "engine_version", "data.aws_rds_engine_version.default", "version"), ), }, }, @@ -81,8 +78,6 @@ func TestAccRDSOrderableInstanceDataSource_preferredVersion(t *testing.T) { func TestAccRDSOrderableInstanceDataSource_preferredClassAndVersion(t *testing.T) { dataSourceName := "data.aws_rds_orderable_db_instance.test" - preferredClass := "db.m3.medium" - preferredVersion := "5.7.22" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccOrderableInstancePreCheck(t) }, @@ -91,10 +86,10 @@ func TestAccRDSOrderableInstanceDataSource_preferredClassAndVersion(t *testing.T CheckDestroy: nil, Steps: []resource.TestStep{ { - Config: testAccOrderableInstanceDataSourceConfig_preferredClassAndVersion(preferredClass, preferredVersion), + Config: testAccOrderableInstanceDataSourceConfig_preferredClassAndVersion(), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "instance_class", preferredClass), - resource.TestCheckResourceAttr(dataSourceName, "engine_version", preferredVersion), + resource.TestCheckResourceAttrPair(dataSourceName, "instance_class", "data.aws_rds_orderable_db_instance.dynamic", "instance_class"), + resource.TestCheckResourceAttrPair(dataSourceName, "engine_version", "data.aws_rds_engine_version.default", "version"), ), }, }, @@ -258,161 +253,217 @@ func testAccOrderableInstancePreCheck(t *testing.T) { } } -func testAccOrderableInstanceDataSourceConfig_basic(class, engine, version, license, storage string) string { +func testAccOrderableInstanceDataSourceConfig_basic(engine, license, storage string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = %[1]q +} + +data "aws_rds_orderable_db_instance" "dynamic" { + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + preferred_instance_classes = [%[2]s] +} + data "aws_rds_orderable_db_instance" "test" { - instance_class = %q - engine = %q - engine_version = %q - license_model = %q - storage_type = %q + instance_class = data.aws_rds_orderable_db_instance.dynamic.instance_class + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + license_model = %[3]q + storage_type = %[4]q } -`, class, engine, version, license, storage) +`, engine, mySQLPreferredInstanceClasses, license, storage) } func testAccOrderableInstanceDataSourceConfig_preferredClass(preferredClass string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" - engine_version = "5.7.22" + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version license_model = "general-public-license" preferred_instance_classes = [ "db.xyz.xlarge", - %q, + %[1]q, "db.t3.small", ] } `, preferredClass) } -func testAccOrderableInstanceDataSourceConfig_preferredVersion(preferredVersion string) string { - return fmt.Sprintf(` +func testAccOrderableInstanceDataSourceConfig_preferredVersion() string { + return ` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" + engine = data.aws_rds_engine_version.default.engine license_model = "general-public-license" storage_type = "standard" preferred_engine_versions = [ "18.42.32", - %q, + data.aws_rds_engine_version.default.version, "not.a.version", ] } -`, preferredVersion) +` } -func testAccOrderableInstanceDataSourceConfig_preferredClassAndVersion(preferredClass, preferredVersion string) string { +func testAccOrderableInstanceDataSourceConfig_preferredClassAndVersion() string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + +data "aws_rds_orderable_db_instance" "dynamic" { + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + preferred_instance_classes = [%[1]s] +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" + engine = data.aws_rds_engine_version.default.engine license_model = "general-public-license" preferred_instance_classes = [ "db.xyz.xlarge", - %q, + data.aws_rds_orderable_db_instance.dynamic.instance_class, "db.t3.small", ] preferred_engine_versions = [ "18.42.32", - %q, + data.aws_rds_engine_version.default.version, "not.a.version", ] } -`, preferredClass, preferredVersion) +`, mySQLPreferredInstanceClasses) } func testAccOrderableInstanceDataSourceConfig_supportsEnhancedMonitoring() string { - return ` + return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" + engine = data.aws_rds_engine_version.default.engine license_model = "general-public-license" storage_type = "standard" supports_enhanced_monitoring = true - preferred_engine_versions = ["8.0.25", "8.0.26", "8.0.27"] - preferred_instance_classes = ["db.t2.small", "db.t3.medium", "db.t3.large"] + preferred_engine_versions = ["8.0.25", "8.0.26", data.aws_rds_engine_version.default.version] + preferred_instance_classes = [%[1]s] } -` +`, mySQLPreferredInstanceClasses) } func testAccOrderableInstanceDataSourceConfig_supportsIAMDatabaseAuthentication() string { - return ` + return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" + engine = data.aws_rds_engine_version.default.engine license_model = "general-public-license" storage_type = "standard" supports_iam_database_authentication = true - preferred_engine_versions = ["8.0.25", "8.0.26", "8.0.27"] - preferred_instance_classes = ["db.t2.small", "db.t3.medium", "db.t3.large"] + preferred_engine_versions = ["8.0.25", "8.0.26", data.aws_rds_engine_version.default.version] + preferred_instance_classes = [%[1]s] } -` +`, mySQLPreferredInstanceClasses) } func testAccOrderableInstanceDataSourceConfig_supportsIops() string { - return ` + return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" + engine = data.aws_rds_engine_version.default.engine license_model = "general-public-license" supports_iops = true - preferred_engine_versions = ["8.0.20", "8.0.19", "8.0.17"] - preferred_instance_classes = ["db.t3.small", "db.t2.xlarge", "db.t2.small"] + preferred_engine_versions = ["8.0.20", "8.0.19", data.aws_rds_engine_version.default.version] + preferred_instance_classes = [%[1]s] } -` +`, mySQLPreferredInstanceClasses) } func testAccOrderableInstanceDataSourceConfig_supportsKerberosAuthentication() string { - return ` + return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "postgres" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "postgres" + engine = data.aws_rds_engine_version.default.engine license_model = "postgresql-license" storage_type = "standard" supports_kerberos_authentication = true - preferred_engine_versions = ["12.3", "11.1", "10.13"] - preferred_instance_classes = ["db.m5.xlarge", "db.r5.large", "db.t3.large"] + preferred_engine_versions = ["14.1", "13.5", data.aws_rds_engine_version.default.version] + preferred_instance_classes = [%[1]s] } -` +`, postgresPreferredInstanceClasses) } func testAccOrderableInstanceDataSourceConfig_supportsPerformanceInsights() string { - return ` + return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" + engine = data.aws_rds_engine_version.default.engine license_model = "general-public-license" supports_performance_insights = true - preferred_engine_versions = ["8.0.25", "8.0.26", "8.0.27"] - preferred_instance_classes = ["db.t2.small", "db.t3.medium", "db.t3.large"] + preferred_engine_versions = ["8.0.25", "8.0.26", data.aws_rds_engine_version.default.version] + preferred_instance_classes = [%[1]s] } -` +`, mySQLPreferredInstanceClasses) } func testAccOrderableInstanceDataSourceConfig_supportsStorageAutoScaling() string { - return ` + return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" + engine = data.aws_rds_engine_version.default.engine license_model = "general-public-license" supports_storage_autoscaling = true - preferred_engine_versions = ["8.0.20", "8.0.19", "5.7.30"] - preferred_instance_classes = ["db.t3.medium", "db.t2.large", "db.t3.xlarge"] + preferred_engine_versions = ["8.0.20", "8.0.19", data.aws_rds_engine_version.default.version] + preferred_instance_classes = [%[1]s] } -` +`, mySQLPreferredInstanceClasses) } func testAccOrderableInstanceDataSourceConfig_supportsStorageEncryption() string { - return ` + return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" + engine = data.aws_rds_engine_version.default.engine license_model = "general-public-license" storage_type = "standard" supports_storage_encryption = true - preferred_engine_versions = ["8.0.25", "8.0.26", "8.0.27"] - preferred_instance_classes = ["db.t2.small", "db.t3.medium", "db.t3.large"] + preferred_engine_versions = ["8.0.25", "8.0.26", data.aws_rds_engine_version.default.version] + preferred_instance_classes = [%[1]s] } -` +`, mySQLPreferredInstanceClasses) } From f164bfcf857d8de7da9853a96de67bbb2f2cce32 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Mar 2022 20:18:04 -0500 Subject: [PATCH 194/229] rds/snapshot: Make version dynamic --- .../service/rds/snapshot_data_source_test.go | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/internal/service/rds/snapshot_data_source_test.go b/internal/service/rds/snapshot_data_source_test.go index 98d27324e19..b7f386d9f4d 100644 --- a/internal/service/rds/snapshot_data_source_test.go +++ b/internal/service/rds/snapshot_data_source_test.go @@ -44,11 +44,21 @@ func testAccCheckSnapshotIDDataSource(n string) resource.TestCheckFunc { func testAccCheckSnapshotDataSourceConfig(rInt int) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + +data "aws_rds_orderable_db_instance" "test" { + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + preferred_instance_classes = [%[1]s] +} + resource "aws_db_instance" "bar" { allocated_storage = 10 - engine = "mysql" - engine_version = "5.6.35" - instance_class = "db.t2.micro" + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + instance_class = data.aws_rds_orderable_db_instance.test.instance_class name = "baz" password = "barbarbarbar" username = "foo" @@ -61,7 +71,7 @@ resource "aws_db_instance" "bar" { backup_retention_period = 0 - parameter_group_name = "default.mysql5.6" + parameter_group_name = "default.${data.aws_rds_engine_version.default.parameter_group_family}" } data "aws_db_snapshot" "snapshot" { @@ -71,7 +81,7 @@ data "aws_db_snapshot" "snapshot" { resource "aws_db_snapshot" "test" { db_instance_identifier = aws_db_instance.bar.id - db_snapshot_identifier = "testsnapshot%d" + db_snapshot_identifier = "testsnapshot%[2]d" } -`, rInt) +`, mySQLPreferredInstanceClasses, rInt) } From be025e23191ba28f5be13b458e1fe1a21637363c Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Mar 2022 20:18:35 -0500 Subject: [PATCH 195/229] snapshot/tests: Dynamic version --- internal/service/rds/enum.go | 75 --------------------------- internal/service/rds/snapshot_test.go | 36 +++++++++---- internal/service/rds/verify.go | 24 +++++++++ 3 files changed, 50 insertions(+), 85 deletions(-) delete mode 100644 internal/service/rds/enum.go create mode 100644 internal/service/rds/verify.go diff --git a/internal/service/rds/enum.go b/internal/service/rds/enum.go deleted file mode 100644 index c31b4aa776e..00000000000 --- a/internal/service/rds/enum.go +++ /dev/null @@ -1,75 +0,0 @@ -package rds - -const ( - ClusterRoleStatusActive = "ACTIVE" - ClusterRoleStatusDeleted = "DELETED" - ClusterRoleStatusPending = "PENDING" -) - -const ( - StorageTypeStandard = "standard" - StorageTypeGp2 = "gp2" - StorageTypeIo1 = "io1" -) - -func StorageType_Values() []string { - return []string{ - StorageTypeStandard, - StorageTypeGp2, - StorageTypeIo1, - } -} - -// https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/accessing-monitoring.html#Overview.DBInstance.Status. -const ( - InstanceStatusAvailable = "available" - InstanceStatusBackingUp = "backing-up" - InstanceStatusConfiguringEnhancedMonitoring = "configuring-enhanced-monitoring" - InstanceStatusConfiguringLogExports = "configuring-log-exports" - InstanceStatusCreating = "creating" - InstanceStatusDeleting = "deleting" - InstanceStatusIncompatibleParameters = "incompatible-parameters" - InstanceStatusIncompatibleRestore = "incompatible-restore" - InstanceStatusModifying = "modifying" - InstanceStatusStarting = "starting" - InstanceStatusStopping = "stopping" - InstanceStatusStorageFull = "storage-full" - InstanceStatusStorageOptimization = "storage-optimization" -) - -const ( - EventSubscriptionStatusActive = "active" - EventSubscriptionStatusCreating = "creating" - EventSubscriptionStatusDeleting = "deleting" - EventSubscriptionStatusModifying = "modifying" -) - -const ( - ExportableLogTypeAgent = "agent" - ExportableLogTypeAlert = "alert" - ExportableLogTypeAudit = "audit" - ExportableLogTypeError = "error" - ExportableLogTypeGeneral = "general" - ExportableLogTypeListener = "listener" - ExportableLogTypeOEMAgent = "oemagent" - ExportableLogTypePostgreSQL = "postgresql" - ExportableLogTypeSlowQuery = "slowquery" - ExportableLogTypeTrace = "trace" - ExportableLogTypeUpgrade = "upgrade" -) - -func ExportableLogType_Values() []string { - return []string{ - ExportableLogTypeAgent, - ExportableLogTypeAlert, - ExportableLogTypeAudit, - ExportableLogTypeError, - ExportableLogTypeGeneral, - ExportableLogTypeListener, - ExportableLogTypeOEMAgent, - ExportableLogTypePostgreSQL, - ExportableLogTypeSlowQuery, - ExportableLogTypeTrace, - ExportableLogTypeUpgrade, - } -} diff --git a/internal/service/rds/snapshot_test.go b/internal/service/rds/snapshot_test.go index 57bcd85a457..7e88039110f 100644 --- a/internal/service/rds/snapshot_test.go +++ b/internal/service/rds/snapshot_test.go @@ -187,33 +187,47 @@ func testAccCheckDbSnapshotDisappears(snapshot *rds.DBSnapshot) resource.TestChe func testAccSnapshotBaseConfig(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + +data "aws_rds_orderable_db_instance" "test" { + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + preferred_instance_classes = ["db.t3.small", "db.t2.small", "db.t2.medium"] +} + resource "aws_db_instance" "test" { allocated_storage = 10 - engine = "mysql" - engine_version = "5.6.35" - instance_class = "db.t2.micro" + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + instance_class = data.aws_rds_orderable_db_instance.test.instance_class name = "baz" identifier = %[1]q password = "barbarbarbar" username = "foo" maintenance_window = "Fri:09:00-Fri:09:30" backup_retention_period = 0 - parameter_group_name = "default.mysql5.6" + parameter_group_name = "default.${data.aws_rds_engine_version.default.parameter_group_family}" skip_final_snapshot = true }`, rName) } func testAccSnapshotConfig(rName string) string { - return testAccSnapshotBaseConfig(rName) + fmt.Sprintf(` + return acctest.ConfigCompose( + testAccSnapshotBaseConfig(rName), + fmt.Sprintf(` resource "aws_db_snapshot" "test" { db_instance_identifier = aws_db_instance.test.id db_snapshot_identifier = %[1]q } -`, rName) +`, rName)) } func testAccSnapshotTags1Config(rName, tag1Key, tag1Value string) string { - return testAccSnapshotBaseConfig(rName) + fmt.Sprintf(` + return acctest.ConfigCompose( + testAccSnapshotBaseConfig(rName), + fmt.Sprintf(` resource "aws_db_snapshot" "test" { db_instance_identifier = aws_db_instance.test.id db_snapshot_identifier = %[1]q @@ -222,11 +236,13 @@ resource "aws_db_snapshot" "test" { %[2]q = %[3]q } } -`, rName, tag1Key, tag1Value) +`, rName, tag1Key, tag1Value)) } func testAccSnapshotTags2Config(rName, tag1Key, tag1Value, tag2Key, tag2Value string) string { - return testAccSnapshotBaseConfig(rName) + fmt.Sprintf(` + return acctest.ConfigCompose( + testAccSnapshotBaseConfig(rName), + fmt.Sprintf(` resource "aws_db_snapshot" "test" { db_instance_identifier = aws_db_instance.test.id db_snapshot_identifier = %[1]q @@ -236,5 +252,5 @@ resource "aws_db_snapshot" "test" { %[4]q = %[5]q } } -`, rName, tag1Key, tag1Value, tag2Key, tag2Value) +`, rName, tag1Key, tag1Value, tag2Key, tag2Value)) } diff --git a/internal/service/rds/verify.go b/internal/service/rds/verify.go new file mode 100644 index 00000000000..11ec581641e --- /dev/null +++ b/internal/service/rds/verify.go @@ -0,0 +1,24 @@ +package rds + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func compareActualEngineVersion(d *schema.ResourceData, oldVersion string, newVersion string) { + newVersionSubstr := newVersion + + if len(newVersion) > len(oldVersion) { + newVersionSubstr = string([]byte(newVersion)[0 : len(oldVersion)+1]) + } + + if oldVersion != newVersion && string(append([]byte(oldVersion), []byte(".")...)) != newVersionSubstr { + d.Set("engine_version", newVersion) + fmt.Printf("[READ/cluster] engine_version: %s\n", newVersion) + } + + d.Set("engine_version_actual", newVersion) + fmt.Printf("[READ/cluster] engine_version_actual: %s\n", newVersion) + +} From ef15f7b92a16a884b150e6b42ec3d9d8a02abf0f Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Tue, 8 Mar 2022 15:36:26 -0500 Subject: [PATCH 196/229] Additional test fixes --- internal/service/rds/instance_test.go | 309 ++++++++++++++------------ internal/service/rds/subnet_group.go | 7 +- internal/service/rds/wait.go | 11 +- 3 files changed, 177 insertions(+), 150 deletions(-) diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index 7c3ac2a553f..1238ddde5d0 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -5,6 +5,7 @@ import ( "log" "os" "regexp" + "strings" "testing" "github.com/aws/aws-sdk-go/aws" @@ -62,8 +63,8 @@ func TestAccRDSInstance_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "license_model", "general-public-license"), resource.TestCheckResourceAttrSet(resourceName, "maintenance_window"), resource.TestCheckResourceAttr(resourceName, "max_allocated_storage", "0"), - resource.TestCheckResourceAttr(resourceName, "option_group_name", "default:mysql-8-0"), - resource.TestCheckResourceAttr(resourceName, "parameter_group_name", "default.mysql8.0"), + resource.TestMatchResourceAttr(resourceName, "option_group_name", regexp.MustCompile(`^default:mysql-\d`)), + resource.TestMatchResourceAttr(resourceName, "parameter_group_name", regexp.MustCompile(`^default\.mysql\d`)), resource.TestCheckResourceAttr(resourceName, "port", "3306"), resource.TestCheckResourceAttr(resourceName, "publicly_accessible", "false"), resource.TestCheckResourceAttrSet(resourceName, "resource_id"), @@ -295,6 +296,7 @@ func TestAccRDSInstance_kmsKey(t *testing.T) { func TestAccRDSInstance_subnetGroup(t *testing.T) { var v rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -305,17 +307,15 @@ func TestAccRDSInstance_subnetGroup(t *testing.T) { { Config: testAccInstanceConfig_WithSubnetGroup(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists("aws_db_instance.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "db_subnet_group_name", "foo-"+rName), + testAccCheckInstanceExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "db_subnet_group_name", rName), ), }, { Config: testAccInstanceConfig_WithSubnetGroupUpdated(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists("aws_db_instance.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "db_subnet_group_name", "bar-"+rName), + testAccCheckInstanceExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "db_subnet_group_name", fmt.Sprintf("%s-2", rName)), ), }, }, @@ -326,6 +326,7 @@ func TestAccRDSInstance_optionGroup(t *testing.T) { var v rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -336,10 +337,9 @@ func TestAccRDSInstance_optionGroup(t *testing.T) { { Config: testAccInstanceConfig_WithOptionGroup(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists("aws_db_instance.bar", &v), + testAccCheckInstanceExists(resourceName, &v), testAccCheckInstanceAttributes(&v), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "option_group_name", rName), + resource.TestCheckResourceAttr(resourceName, "option_group_name", rName), ), }, }, @@ -699,7 +699,7 @@ func TestAccRDSInstance_password(t *testing.T) { }) } -func TestAccRDSInstance_replicateSourceDB_basic(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_basic(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -736,7 +736,7 @@ func TestAccRDSInstance_replicateSourceDB_basic(t *testing.T) { }) } -func TestAccRDSInstance_replicateSourceDB_namePrefix(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_namePrefix(t *testing.T) { var v rds.DBInstance sourceName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -769,7 +769,7 @@ func TestAccRDSInstance_replicateSourceDB_namePrefix(t *testing.T) { }) } -func TestAccRDSInstance_replicateSourceDB_nameGenerated(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_nameGenerated(t *testing.T) { var v rds.DBInstance sourceName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -801,7 +801,7 @@ func TestAccRDSInstance_replicateSourceDB_nameGenerated(t *testing.T) { }) } -func TestAccRDSInstance_replicateSourceDB_addLater(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_addLater(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1310,7 +1310,7 @@ func TestAccRDSInstance_ReplicateSourceDB_multiAZ(t *testing.T) { }) } -func TestAccRDSInstance_ReplicateSourceDB_parameterGroupName_sameSetOnBoth(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_parameterGroupNameSameSetOnBoth(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1339,7 +1339,7 @@ func TestAccRDSInstance_ReplicateSourceDB_parameterGroupName_sameSetOnBoth(t *te }) } -func TestAccRDSInstance_ReplicateSourceDB_parameterGroupName_differentSetOnBoth(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_parameterGroupNameDifferentSetOnBoth(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1368,7 +1368,7 @@ func TestAccRDSInstance_ReplicateSourceDB_parameterGroupName_differentSetOnBoth( }) } -func TestAccRDSInstance_ReplicateSourceDB_parameterGroupName_replicaCopiesValue(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_parameterGroupNameReplicaCopiesValue(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1396,7 +1396,7 @@ func TestAccRDSInstance_ReplicateSourceDB_parameterGroupName_replicaCopiesValue( }) } -func TestAccRDSInstance_ReplicateSourceDB_parameterGroupName_setOnReplica(t *testing.T) { +func TestAccRDSInstance_ReplicateSourceDB_parameterGroupNameSetOnReplica(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1572,7 +1572,7 @@ func TestAccRDSInstance_ReplicateSourceDB_parameterGroupTwoStep(t *testing.T) { }) } -func TestAccRDSInstance_s3Import_basic(t *testing.T) { +func TestAccRDSInstance_S3Import_basic(t *testing.T) { var snap rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) bucketPrefix := sdkacctest.RandString(5) @@ -1605,7 +1605,7 @@ func TestAccRDSInstance_s3Import_basic(t *testing.T) { }) } -func TestAccRDSInstance_s3Import_NameDeprecated_basic(t *testing.T) { +func TestAccRDSInstance_S3Import_nameDeprecated(t *testing.T) { var snap rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) bucketPrefix := sdkacctest.RandString(5) @@ -1638,7 +1638,7 @@ func TestAccRDSInstance_s3Import_NameDeprecated_basic(t *testing.T) { }) } -func TestAccRDSInstance_s3Import_namePrefix(t *testing.T) { +func TestAccRDSInstance_S3Import_namePrefix(t *testing.T) { var snap rds.DBInstance const identifierPrefix = "tf-acc-test-prefix-" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1672,7 +1672,7 @@ func TestAccRDSInstance_s3Import_namePrefix(t *testing.T) { }) } -func TestAccRDSInstance_s3Import_nameGenerated(t *testing.T) { +func TestAccRDSInstance_S3Import_nameGenerated(t *testing.T) { var snap rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) bucketPrefix := sdkacctest.RandString(5) @@ -1983,7 +1983,7 @@ func TestAccRDSInstance_SnapshotIdentifier_availabilityZone(t *testing.T) { }) } -func TestAccRDSInstance_SnapshotIdentifier_backupRetentionPeriod_override(t *testing.T) { +func TestAccRDSInstance_SnapshotIdentifier_backupRetentionPeriodOverride(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2011,7 +2011,7 @@ func TestAccRDSInstance_SnapshotIdentifier_backupRetentionPeriod_override(t *tes }) } -func TestAccRDSInstance_SnapshotIdentifier_backupRetentionPeriod_unset(t *testing.T) { +func TestAccRDSInstance_SnapshotIdentifier_backupRetentionPeriodUnset(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2098,7 +2098,7 @@ func TestAccRDSInstance_SnapshotIdentifier_dbSubnetGroupName(t *testing.T) { }) } -func TestAccRDSInstance_SnapshotIdentifier_DBSubnetGroupName_ramShared(t *testing.T) { +func TestAccRDSInstance_SnapshotIdentifier_dbSubnetGroupNameRAMShared(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot var dbSubnetGroup rds.DBSubnetGroup @@ -2134,7 +2134,7 @@ func TestAccRDSInstance_SnapshotIdentifier_DBSubnetGroupName_ramShared(t *testin }) } -func TestAccRDSInstance_SnapshotIdentifier_DBSubnetGroupName_vpcSecurityGroupIDs(t *testing.T) { +func TestAccRDSInstance_SnapshotIdentifier_dbSubnetGroupNameVPCSecurityGroupIDs(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot var dbSubnetGroup rds.DBSubnetGroup @@ -2343,7 +2343,7 @@ func TestAccRDSInstance_SnapshotIdentifier_multiAZ(t *testing.T) { }) } -func TestAccRDSInstance_SnapshotIdentifier_multiAZ_sqlServer(t *testing.T) { +func TestAccRDSInstance_SnapshotIdentifier_multiAZSQLServer(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2457,8 +2457,8 @@ func TestAccRDSInstance_SnapshotIdentifier_tags(t *testing.T) { }) } -func TestAccRDSInstance_SnapshotIdentifier_Tags_Clear(t *testing.T) { - acctest.Skip(t, "To be fixed: https://github.com/hashicorp/terraform-provider-aws/issues/5959") +func TestAccRDSInstance_SnapshotIdentifier_tagsRemove(t *testing.T) { + //acctest.Skip(t, "To be fixed: https://github.com/hashicorp/terraform-provider-aws/issues/5959") // --- FAIL: TestAccRDSInstance_SnapshotIdentifierTags_unset (1086.15s) // testing.go:527: Step 0 error: Check failed: Check 4/4 error: aws_db_instance.test: Attribute 'tags.%' expected "0", got "1" @@ -2520,7 +2520,7 @@ func TestAccRDSInstance_SnapshotIdentifier_vpcSecurityGroupIDs(t *testing.T) { // This acceptance test explicitly tests when snapshot_identifier is set, // vpc_security_group_ids is set (which triggered the resource update function), // and tags is set which was missing its ARN used for tagging -func TestAccRDSInstance_SnapshotIdentifier_vpcSecurityGroupIDs_tags(t *testing.T) { +func TestAccRDSInstance_SnapshotIdentifier_vpcSecurityGroupIDsTags(t *testing.T) { var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2761,6 +2761,7 @@ func TestAccRDSInstance_portUpdate(t *testing.T) { var v rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2771,18 +2772,16 @@ func TestAccRDSInstance_portUpdate(t *testing.T) { { Config: testAccInstanceConfig_SnapshotInstanceConfig_mySQLPort(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists("aws_db_instance.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "port", "3306"), + testAccCheckInstanceExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "port", "3306"), ), }, { Config: testAccInstanceConfig_SnapshotInstanceConfig_updateMySQLPort(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists("aws_db_instance.bar", &v), - resource.TestCheckResourceAttr( - "aws_db_instance.bar", "port", "3305"), + testAccCheckInstanceExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "port", "3305"), ), }, }, @@ -2891,6 +2890,8 @@ func TestAccRDSInstance_MSSQL_domainSnapshotRestore(t *testing.T) { func TestAccRDSInstance_MySQL_snapshotRestoreWithEngineVersion(t *testing.T) { var v, vRestoredInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_db_instance.test" + restoreResourceName := "aws_db_instance.restore" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -2901,10 +2902,11 @@ func TestAccRDSInstance_MySQL_snapshotRestoreWithEngineVersion(t *testing.T) { { Config: testAccInstanceConfig_MySQLSnapshotRestoreWithEngineVersion(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckInstanceExists("aws_db_instance.mysql_restore", &vRestoredInstance), - testAccCheckInstanceExists("aws_db_instance.mysql", &v), - resource.TestCheckResourceAttr("aws_db_instance.mysql", "engine_version", "8.0.23"), - resource.TestCheckResourceAttr("aws_db_instance.mysql_restore", "engine_version", "8.0.25"), + testAccCheckInstanceExists(restoreResourceName, &vRestoredInstance), + testAccCheckInstanceExists(resourceName, &v), + // Hardcoded older version. Will to update when no longer compatible to upgrade from this to the default version. + resource.TestCheckResourceAttr(resourceName, "engine_version", "8.0.25"), + resource.TestCheckResourceAttrPair(restoreResourceName, "engine_version", "data.aws_rds_engine_version.default", "version"), ), }, }, @@ -3334,12 +3336,12 @@ func testAccCheckInstanceSnapshot(s *terraform.State) error { var found bool for _, t := range listTagsOutput.TagList { - if *t.Key == "Name" && *t.Value == "tf-tags-db" { + if aws.StringValue(t.Key) == "Name" && strings.HasPrefix(aws.StringValue(t.Value), acctest.ResourcePrefix) { found = true } } if !found { - return fmt.Errorf("Expected to find tag Name (%s), but wasn't found. Tags: %s", "tf-tags-db", listTagsOutput.TagList) + return fmt.Errorf("Expected to find tag Name with prefix \"%s\", but wasn't found. Tags: %s", acctest.ResourcePrefix, listTagsOutput.TagList) } // end tag search @@ -4327,7 +4329,7 @@ resource "aws_db_option_group" "test" { option_group_description = "Test option group for terraform" } -resource "aws_db_instance" "bar" { +resource "aws_db_instance" "test" { allocated_storage = 10 engine = aws_db_option_group.test.engine_name engine_version = aws_db_option_group.test.major_engine_version @@ -4904,8 +4906,10 @@ resource "aws_db_instance" "bar" { } func testAccInstanceConfig_SnapshotInstanceConfig_mySQLPort(rName string) string { - return acctest.ConfigCompose(testAccInstanceConfig_orderableClassMySQL(), fmt.Sprintf(` -resource "aws_db_instance" "bar" { + return acctest.ConfigCompose( + testAccInstanceConfig_orderableClassMySQL(), + fmt.Sprintf(` +resource "aws_db_instance" "test" { identifier = %[1]q engine = data.aws_rds_orderable_db_instance.test.engine engine_version = data.aws_rds_orderable_db_instance.test.engine_version @@ -4924,8 +4928,10 @@ resource "aws_db_instance" "bar" { } func testAccInstanceConfig_SnapshotInstanceConfig_updateMySQLPort(rName string) string { - return acctest.ConfigCompose(testAccInstanceConfig_orderableClassMySQL(), fmt.Sprintf(` -resource "aws_db_instance" "bar" { + return acctest.ConfigCompose( + testAccInstanceConfig_orderableClassMySQL(), + fmt.Sprintf(` +resource "aws_db_instance" "test" { identifier = %[1]q engine = data.aws_rds_orderable_db_instance.test.engine engine_version = data.aws_rds_orderable_db_instance.test.engine_version @@ -4948,7 +4954,7 @@ func testAccInstanceConfig_WithSubnetGroup(rName string) string { testAccInstanceConfig_orderableClassMySQL(), acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` -resource "aws_vpc" "foo" { +resource "aws_vpc" "test" { cidr_block = "10.1.0.0/16" tags = { @@ -4956,36 +4962,36 @@ resource "aws_vpc" "foo" { } } -resource "aws_subnet" "foo" { +resource "aws_subnet" "test" { cidr_block = "10.1.1.0/24" availability_zone = data.aws_availability_zones.available.names[0] - vpc_id = aws_vpc.foo.id + vpc_id = aws_vpc.test.id tags = { Name = %[1]q } } -resource "aws_subnet" "bar" { +resource "aws_subnet" "test2" { cidr_block = "10.1.2.0/24" availability_zone = data.aws_availability_zones.available.names[1] - vpc_id = aws_vpc.foo.id + vpc_id = aws_vpc.test.id tags = { Name = "%[1]s-2" } } -resource "aws_db_subnet_group" "foo" { +resource "aws_db_subnet_group" "test" { name = %[1]q - subnet_ids = [aws_subnet.foo.id, aws_subnet.bar.id] + subnet_ids = [aws_subnet.test.id, aws_subnet.test2.id] tags = { Name = %[1]q } } -resource "aws_db_instance" "bar" { +resource "aws_db_instance" "test" { identifier = %[1]q engine = data.aws_rds_orderable_db_instance.test.engine engine_version = data.aws_rds_orderable_db_instance.test.engine_version @@ -4994,7 +5000,7 @@ resource "aws_db_instance" "bar" { username = "foo" password = "barbarbar" parameter_group_name = "default.${data.aws_rds_engine_version.default.parameter_group_family}" - db_subnet_group_name = aws_db_subnet_group.foo.name + db_subnet_group_name = aws_db_subnet_group.test.name port = 3305 allocated_storage = 10 skip_final_snapshot = true @@ -5010,7 +5016,7 @@ func testAccInstanceConfig_WithSubnetGroupUpdated(rName string) string { testAccInstanceConfig_orderableClassMySQL(), acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` -resource "aws_vpc" "foo" { +resource "aws_vpc" "test" { cidr_block = "10.1.0.0/16" tags = { @@ -5018,73 +5024,73 @@ resource "aws_vpc" "foo" { } } -resource "aws_vpc" "bar" { - cidr_block = "10.10.0.0/16" +resource "aws_subnet" "test" { + cidr_block = "10.1.1.0/24" + availability_zone = data.aws_availability_zones.available.names[0] + vpc_id = aws_vpc.test.id tags = { Name = %[1]q } } -resource "aws_subnet" "foo" { - cidr_block = "10.1.1.0/24" - availability_zone = data.aws_availability_zones.available.names[0] - vpc_id = aws_vpc.foo.id +resource "aws_subnet" "test2" { + cidr_block = "10.1.2.0/24" + availability_zone = data.aws_availability_zones.available.names[1] + vpc_id = aws_vpc.test.id + + tags = { + Name = "%[1]s-2" + } +} + +resource "aws_db_subnet_group" "test" { + name = %[1]q + subnet_ids = [aws_subnet.test.id, aws_subnet.test2.id] tags = { Name = %[1]q } } -resource "aws_subnet" "bar" { - cidr_block = "10.1.2.0/24" - availability_zone = data.aws_availability_zones.available.names[1] - vpc_id = aws_vpc.foo.id +resource "aws_vpc" "test2" { + cidr_block = "10.10.0.0/16" tags = { Name = "%[1]s-2" } } -resource "aws_subnet" "test" { +resource "aws_subnet" "test3" { cidr_block = "10.10.3.0/24" availability_zone = data.aws_availability_zones.available.names[1] - vpc_id = aws_vpc.bar.id + vpc_id = aws_vpc.test2.id tags = { Name = "%[1]s-3" } } -resource "aws_subnet" "another_test" { +resource "aws_subnet" "test4" { cidr_block = "10.10.4.0/24" availability_zone = data.aws_availability_zones.available.names[0] - vpc_id = aws_vpc.bar.id + vpc_id = aws_vpc.test2.id tags = { Name = "%[1]s-4" } } -resource "aws_db_subnet_group" "foo" { - name = "%[1]s-1" - subnet_ids = [aws_subnet.foo.id, aws_subnet.bar.id] - - tags = { - Name = %[1]q - } -} - -resource "aws_db_subnet_group" "bar" { +resource "aws_db_subnet_group" "test2" { name = "%[1]s-2" - subnet_ids = [aws_subnet.test.id, aws_subnet.another_test.id] + subnet_ids = [aws_subnet.test3.id, aws_subnet.test4.id] tags = { Name = "%[1]s-2" } } -resource "aws_db_instance" "bar" { +resource "aws_db_instance" "test" { identifier = %[1]q engine = data.aws_rds_orderable_db_instance.test.engine engine_version = data.aws_rds_orderable_db_instance.test.engine_version @@ -5093,14 +5099,15 @@ resource "aws_db_instance" "bar" { username = "foo" password = "barbarbar" parameter_group_name = "default.${data.aws_rds_engine_version.default.parameter_group_family}" - db_subnet_group_name = aws_db_subnet_group.bar.name + db_subnet_group_name = aws_db_subnet_group.test2.name port = 3305 allocated_storage = 10 skip_final_snapshot = true backup_retention_period = 0 + apply_immediately = true - apply_immediately = true + depends_on = [aws_db_subnet_group.test] } `, rName)) } @@ -5461,7 +5468,7 @@ func testAccInstanceConfig_MySQLSnapshotRestoreWithEngineVersion(rName string) s testAccInstanceConfig_orderableClassMySQL(), acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` -resource "aws_vpc" "foo" { +resource "aws_vpc" "test" { cidr_block = "10.1.0.0/16" enable_dns_hostnames = true @@ -5470,15 +5477,14 @@ resource "aws_vpc" "foo" { } } -resource "aws_db_subnet_group" "rds_one" { +resource "aws_db_subnet_group" "test" { name = %[1]q - description = "db subnets for rds_one" - - subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] + description = "db subnets" + subnet_ids = [aws_subnet.test.id, aws_subnet.test2.id] } -resource "aws_subnet" "main" { - vpc_id = aws_vpc.foo.id +resource "aws_subnet" "test" { + vpc_id = aws_vpc.test.id availability_zone = data.aws_availability_zones.available.names[0] cidr_block = "10.1.1.0/24" @@ -5487,8 +5493,8 @@ resource "aws_subnet" "main" { } } -resource "aws_subnet" "other" { - vpc_id = aws_vpc.foo.id +resource "aws_subnet" "test2" { + vpc_id = aws_vpc.test.id availability_zone = data.aws_availability_zones.available.names[1] cidr_block = "10.1.2.0/24" @@ -5497,10 +5503,10 @@ resource "aws_subnet" "other" { } } -resource "aws_db_instance" "mysql" { +resource "aws_db_instance" "test" { allocated_storage = 20 - engine = data.aws_rds_orderable_db_instance.test.engine - engine_version = data.aws_rds_orderable_db_instance.test.engine_version + engine = data.aws_rds_engine_version.default.engine + engine_version = "8.0.25" # test is from older to newer version, update when restore from this to current default version is incompatible identifier = %[1]q instance_class = data.aws_rds_orderable_db_instance.test.instance_class password = "password" @@ -5508,45 +5514,42 @@ resource "aws_db_instance" "mysql" { username = "root" } -resource "aws_db_snapshot" "mysql-snap" { - db_instance_identifier = aws_db_instance.mysql.id +resource "aws_db_snapshot" "test" { + db_instance_identifier = aws_db_instance.test.id db_snapshot_identifier = %[1]q } -resource "aws_db_instance" "mysql_restore" { - identifier = "%[1]s-restore" - - db_subnet_group_name = aws_db_subnet_group.rds_one.name - - instance_class = data.aws_rds_orderable_db_instance.test.instance_class +resource "aws_db_instance" "restore" { allocated_storage = 20 - username = "root" - password = "password" - engine = data.aws_rds_orderable_db_instance.test.engine - engine_version = "8.0.25" + apply_immediately = true backup_retention_period = 0 + db_subnet_group_name = aws_db_subnet_group.test.name + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + identifier = "%[1]s-restore" + instance_class = data.aws_rds_orderable_db_instance.test.instance_class + password = "password" skip_final_snapshot = true - snapshot_identifier = aws_db_snapshot.mysql-snap.id - - apply_immediately = true - vpc_security_group_ids = [aws_security_group.rds-mysql.id] + snapshot_identifier = aws_db_snapshot.test.id + username = "root" + vpc_security_group_ids = [aws_security_group.test.id] } -resource "aws_security_group" "rds-mysql" { +resource "aws_security_group" "test" { name = %[1]q description = "TF Testing" - vpc_id = aws_vpc.foo.id + vpc_id = aws_vpc.test.id } -resource "aws_security_group_rule" "rds-mysql-1" { +resource "aws_security_group_rule" "test" { type = "egress" from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] - security_group_id = aws_security_group.rds-mysql.id + security_group_id = aws_security_group.test.id } `, rName)) } @@ -5569,12 +5572,14 @@ resource "aws_db_instance" "test" { } func testAccInstanceConfig_AutoMinorVersion(rName string) string { - return acctest.ConfigCompose(testAccInstanceConfig_orderableClassMySQL(), fmt.Sprintf(` + return acctest.ConfigCompose( + testAccInstanceConfig_orderableClassMySQL(), + fmt.Sprintf(` resource "aws_db_instance" "bar" { identifier = %[1]q allocated_storage = 10 - engine = data.aws_rds_orderable_db_instance.test.engine - engine_version = "8.0" + engine = data.aws_rds_engine_version.default.engine + engine_version = regex("^\\d+\\.\\d+", data.aws_rds_engine_version.default.version) instance_class = data.aws_rds_orderable_db_instance.test.instance_class db_name = "baz" password = "barbarbarbar" @@ -6591,15 +6596,20 @@ resource "aws_db_subnet_group" "test" { subnet_ids = aws_subnet.test[*].id } +data "aws_rds_engine_version" "default" { + provider = "awsalternate" + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { provider = "awsalternate" - engine = "mysql" - engine_version = "8.0.23" + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version license_model = "general-public-license" storage_type = "standard" - preferred_instance_classes = ["db.t3.micro", "db.t2.micro", "db.t2.medium"] + preferred_instance_classes = [%[2]s] } resource "aws_db_instance" "source" { @@ -6608,7 +6618,7 @@ resource "aws_db_instance" "source" { allocated_storage = 5 backup_retention_period = 1 db_subnet_group_name = aws_db_subnet_group.alternate.name - engine = data.aws_rds_orderable_db_instance.test.engine + engine = data.aws_rds_engine_version.default.engine identifier = "%[1]s-source" instance_class = data.aws_rds_orderable_db_instance.test.instance_class password = "avoid-plaintext-passwords" @@ -6623,7 +6633,7 @@ resource "aws_db_instance" "test" { replicate_source_db = aws_db_instance.source.arn skip_final_snapshot = true } -`, rName)) +`, rName, mySQLPreferredInstanceClasses)) } // When testing needs to distinguish a second region and second account in the same region @@ -6764,15 +6774,20 @@ resource "aws_security_group" "test" { vpc_id = aws_vpc.alternateaccountsameregion.id } +data "aws_rds_engine_version" "default" { + provider = "awssameaccountalternateregion" + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { provider = "awssameaccountalternateregion" - engine = "mysql" - engine_version = "8.0.23" + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version license_model = "general-public-license" storage_type = "standard" - preferred_instance_classes = ["db.t3.micro", "db.t2.micro", "db.t2.medium"] + preferred_instance_classes = [%[2]s] } resource "aws_db_instance" "source" { @@ -6781,7 +6796,8 @@ resource "aws_db_instance" "source" { allocated_storage = 5 backup_retention_period = 1 db_subnet_group_name = aws_db_subnet_group.sameaccountalternateregion.name - engine = data.aws_rds_orderable_db_instance.test.engine + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version identifier = "%[1]s-source" instance_class = data.aws_rds_orderable_db_instance.test.instance_class password = "avoid-plaintext-passwords" @@ -6797,7 +6813,7 @@ resource "aws_db_instance" "test" { skip_final_snapshot = true vpc_security_group_ids = [aws_security_group.test.id] } -`, rName)) +`, rName, mySQLPreferredInstanceClasses)) } func testAccInstanceConfig_ReplicateSourceDB_DbSubnetGroupName_VPCSecurityGroupIDs(rName string) string { @@ -6876,15 +6892,20 @@ resource "aws_db_subnet_group" "test" { subnet_ids = aws_subnet.test[*].id } +data "aws_rds_engine_version" "default" { + provider = "awsalternate" + engine = "mysql" +} + data "aws_rds_orderable_db_instance" "test" { provider = "awsalternate" - engine = "mysql" - engine_version = "8.0.23" + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version license_model = "general-public-license" storage_type = "standard" - preferred_instance_classes = ["db.t3.micro", "db.t2.micro", "db.t2.medium"] + preferred_instance_classes = [%[2]s] } resource "aws_db_instance" "source" { @@ -6909,7 +6930,7 @@ resource "aws_db_instance" "test" { skip_final_snapshot = true vpc_security_group_ids = [aws_security_group.test.id] } -`, rName)) +`, rName, mySQLPreferredInstanceClasses)) } func testAccInstanceConfig_ReplicateSourceDB_DeletionProtection(rName string, deletionProtection bool) string { @@ -7611,9 +7632,9 @@ resource "aws_db_instance" "test" { func testAccInstanceConfig_SnapshotIdentifier_AllowMajorVersionUpgrade(rName string, allowMajorVersionUpgrade bool) string { return fmt.Sprintf(` -data "aws_rds_orderable_db_instance" "postgres10" { +data "aws_rds_orderable_db_instance" "postgres13" { engine = "postgres" - engine_version = "10.1" + engine_version = "13.5" license_model = "postgresql-license" storage_type = "standard" @@ -7622,10 +7643,10 @@ data "aws_rds_orderable_db_instance" "postgres10" { resource "aws_db_instance" "source" { allocated_storage = 5 - engine = data.aws_rds_orderable_db_instance.postgres10.engine - engine_version = data.aws_rds_orderable_db_instance.postgres10.engine_version + engine = data.aws_rds_orderable_db_instance.postgres13.engine + engine_version = data.aws_rds_orderable_db_instance.postgres13.engine_version identifier = "%[1]s-source" - instance_class = data.aws_rds_orderable_db_instance.postgres10.instance_class + instance_class = data.aws_rds_orderable_db_instance.postgres13.instance_class password = "avoid-plaintext-passwords" username = "tfacctest" skip_final_snapshot = true @@ -7636,9 +7657,9 @@ resource "aws_db_snapshot" "test" { db_snapshot_identifier = %[1]q } -data "aws_rds_orderable_db_instance" "postgres11" { +data "aws_rds_orderable_db_instance" "postgres14" { engine = "postgres" - engine_version = "11.1" + engine_version = "14.1" license_model = "postgresql-license" storage_type = "standard" @@ -7647,8 +7668,8 @@ data "aws_rds_orderable_db_instance" "postgres11" { resource "aws_db_instance" "test" { allow_major_version_upgrade = %[2]t - engine = data.aws_rds_orderable_db_instance.postgres11.engine - engine_version = data.aws_rds_orderable_db_instance.postgres11.engine_version + engine = data.aws_rds_orderable_db_instance.postgres14.engine + engine_version = data.aws_rds_orderable_db_instance.postgres14.engine_version identifier = %[1]q instance_class = aws_db_instance.source.instance_class snapshot_identifier = aws_db_snapshot.test.id diff --git a/internal/service/rds/subnet_group.go b/internal/service/rds/subnet_group.go index 47a29fe7fe6..a3c0ba1894e 100644 --- a/internal/service/rds/subnet_group.go +++ b/internal/service/rds/subnet_group.go @@ -222,7 +222,12 @@ func resourceSubnetGroupDelete(d *schema.ResourceData, meta interface{}) error { MinTimeout: 1 * time.Second, } _, err := stateConf.WaitForState() - return err + + if err != nil { + return fmt.Errorf("deleting RDS Subnet Group (%s): %w", d.Id(), err) + } + + return nil } func resourceSubnetGroupDeleteRefreshFunc( diff --git a/internal/service/rds/wait.go b/internal/service/rds/wait.go index a3917df1d14..2edd2eb0326 100644 --- a/internal/service/rds/wait.go +++ b/internal/service/rds/wait.go @@ -161,11 +161,12 @@ func waitDBInstanceDeleted(conn *rds.RDS, id string, timeout time.Duration) (*rd InstanceStatusStorageFull, InstanceStatusStorageOptimization, }, - Target: []string{}, - Refresh: statusDBInstance(conn, id), - Timeout: timeout, - MinTimeout: 10 * time.Second, - Delay: 30 * time.Second, + Target: []string{}, + Refresh: statusDBInstance(conn, id), + Timeout: timeout, + MinTimeout: 10 * time.Second, + Delay: 30 * time.Second, + ContinuousTargetOccurence: 3, } outputRaw, err := stateConf.WaitForState() From 7a6db9d363ec6903b750db7a067d228f801cf65b Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Tue, 8 Mar 2022 15:37:13 -0500 Subject: [PATCH 197/229] Continue skipping unfixed test --- internal/service/rds/instance_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index 1238ddde5d0..ecbed815231 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -2458,7 +2458,7 @@ func TestAccRDSInstance_SnapshotIdentifier_tags(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_tagsRemove(t *testing.T) { - //acctest.Skip(t, "To be fixed: https://github.com/hashicorp/terraform-provider-aws/issues/5959") + acctest.Skip(t, "To be fixed: https://github.com/hashicorp/terraform-provider-aws/issues/5959") // --- FAIL: TestAccRDSInstance_SnapshotIdentifierTags_unset (1086.15s) // testing.go:527: Step 0 error: Check failed: Check 4/4 error: aws_db_instance.test: Attribute 'tags.%' expected "0", got "1" From bd79e33f57d2c3ab382c2a8a241200bf058a010f Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Tue, 8 Mar 2022 16:27:47 -0500 Subject: [PATCH 198/229] Flint and steel --- internal/service/rds/global_cluster_test.go | 1 - internal/service/rds/instance.go | 9 +++++++-- internal/service/rds/instance_test.go | 16 ++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index 586ffe58f26..ffb72cf43ec 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -602,7 +602,6 @@ resource "aws_rds_cluster" "test" { resource "aws_rds_cluster_instance" "test" { apply_immediately = true cluster_identifier = aws_rds_cluster.test.id - #cluster_identifier = %[3]q engine = %[1]q engine_version = %[2]q identifier = %[3]q diff --git a/internal/service/rds/instance.go b/internal/service/rds/instance.go index c8cfbe783df..a4b4c4c20ed 100644 --- a/internal/service/rds/instance.go +++ b/internal/service/rds/instance.go @@ -1808,7 +1808,7 @@ func resourceInstanceUpdate(d *schema.ResourceData, meta interface{}) error { if requestUpdate { log.Printf("[DEBUG] DB Instance Modification request: %s", req) - err := resource.Retry(tfiam.PropagationTimeout, func() *resource.RetryError { + err := resource.Retry(d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError { _, err := conn.ModifyDBInstance(req) // Retry for IAM eventual consistency @@ -1816,6 +1816,11 @@ func resourceInstanceUpdate(d *schema.ResourceData, meta interface{}) error { return resource.RetryableError(err) } + // InvalidDBInstanceState: RDS is configuring Enhanced Monitoring or Performance Insights for this DB instance. Try your request later. + if tfawserr.ErrMessageContains(err, rds.ErrCodeInvalidDBInstanceStateFault, "your request later") { + return resource.RetryableError(err) + } + if err != nil { return resource.NonRetryableError(err) } @@ -1828,7 +1833,7 @@ func resourceInstanceUpdate(d *schema.ResourceData, meta interface{}) error { } if err != nil { - return fmt.Errorf("Error modifying DB Instance %s: %w", d.Id(), err) + return fmt.Errorf("modifying DB Instance %s: %w", d.Id(), err) } log.Printf("[DEBUG] Waiting for DB Instance (%s) to be available", d.Id()) diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index ecbed815231..4a37d60c133 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -5480,7 +5480,7 @@ resource "aws_vpc" "test" { resource "aws_db_subnet_group" "test" { name = %[1]q description = "db subnets" - subnet_ids = [aws_subnet.test.id, aws_subnet.test2.id] + subnet_ids = [aws_subnet.test.id, aws_subnet.test2.id] } resource "aws_subnet" "test" { @@ -5606,8 +5606,7 @@ resource "aws_vpc" "foo" { resource "aws_db_subnet_group" "rds_one" { name = %[1]q description = "db subnets for rds_one" - - subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] + subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] } resource "aws_subnet" "main" { @@ -5668,8 +5667,7 @@ resource "aws_vpc" "foo" { resource "aws_db_subnet_group" "rds_one" { name = %[1]q description = "db subnets for rds_one" - - subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] + subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] } resource "aws_subnet" "main" { @@ -5733,8 +5731,7 @@ resource "aws_vpc" "foo" { resource "aws_db_subnet_group" "rds_one" { name = %[1]q description = "db subnets for rds_one" - - subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] + subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] } resource "aws_subnet" "main" { @@ -5798,8 +5795,7 @@ resource "aws_vpc" "foo" { resource "aws_db_subnet_group" "rds_one" { name = %[1]q description = "db subnets for rds_one" - - subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] + subnet_ids = [aws_subnet.main.id, aws_subnet.other.id] } resource "aws_subnet" "main" { @@ -6597,7 +6593,7 @@ resource "aws_db_subnet_group" "test" { } data "aws_rds_engine_version" "default" { - provider = "awsalternate" + provider = "awsalternate" engine = "mysql" } From 2706b53a072e1491bec7ae24b9f123fd60e9924b Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Tue, 8 Mar 2022 16:32:21 -0500 Subject: [PATCH 199/229] More flint --- internal/service/rds/cluster.go | 4 ---- internal/service/rds/global_cluster.go | 3 --- internal/service/rds/instance_test.go | 4 ++-- internal/service/rds/verify.go | 5 ----- 4 files changed, 2 insertions(+), 14 deletions(-) diff --git a/internal/service/rds/cluster.go b/internal/service/rds/cluster.go index 31391e56678..4836782c5bd 100644 --- a/internal/service/rds/cluster.go +++ b/internal/service/rds/cluster.go @@ -559,7 +559,6 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { } if attr, ok := d.GetOk("engine_version"); ok { - fmt.Printf("[CREATE/cluster/snapshot_identifier] engine_version: %s\n", attr.(string)) opts.EngineVersion = aws.String(attr.(string)) } @@ -655,7 +654,6 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { } if attr, ok := d.GetOk("engine_version"); ok { - fmt.Printf("[CREATE/cluster/s3_import] engine_version: %s\n", attr.(string)) createOpts.EngineVersion = aws.String(attr.(string)) } @@ -873,7 +871,6 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { } if attr, ok := d.GetOk("engine_version"); ok { - fmt.Printf("[CREATE/cluster/else] engine_version: %s\n", attr.(string)) createOpts.EngineVersion = aws.String(attr.(string)) } @@ -1186,7 +1183,6 @@ func resourceClusterUpdate(d *schema.ResourceData, meta interface{}) error { } if d.HasChange("engine_version") { - fmt.Printf("[UPDATE/cluster] engine_version: %s\n", d.Get("engine_version").(string)) req.EngineVersion = aws.String(d.Get("engine_version").(string)) requestUpdate = true } diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index 674f4e6fa79..28bd6004fec 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -128,7 +128,6 @@ func resourceGlobalClusterCreate(d *schema.ResourceData, meta interface{}) error } if v, ok := d.GetOk("engine_version"); ok { - fmt.Printf("[CREATE/global_cluster] engine_version: %s\n", v.(string)) input.EngineVersion = aws.String(v.(string)) } @@ -193,7 +192,6 @@ func resourceGlobalClusterRead(d *schema.ResourceData, meta interface{}) error { d.Set("deletion_protection", globalCluster.DeletionProtection) d.Set("engine", globalCluster.Engine) d.Set("engine_version", globalCluster.EngineVersion) - fmt.Printf("[READ/global_cluster] engine_verison: %s\n", aws.StringValue(globalCluster.EngineVersion)) d.Set("global_cluster_identifier", globalCluster.GlobalClusterIdentifier) if err := d.Set("global_cluster_members", flattenGlobalClusterMembers(globalCluster.GlobalClusterMembers)); err != nil { @@ -215,7 +213,6 @@ func resourceGlobalClusterUpdate(d *schema.ResourceData, meta interface{}) error } if d.HasChange("engine_version") { - fmt.Printf("[UPDATE/global_cluster] engine_version: %s\n", d.Get("engine_version").(string)) if err := resourceGlobalClusterUpgradeEngineVersion(d, conn); err != nil { return err } diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index 4a37d60c133..ca3b4baaf4b 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -4185,7 +4185,7 @@ resource "aws_db_instance" "test" { func testAccInstanceConfig_MajorVersionOnly() string { return acctest.ConfigCompose( testAccInstanceConfig_orderableClassMySQL(), - fmt.Sprintf(` + ` resource "aws_db_instance" "test" { allocated_storage = 10 backup_retention_period = 0 @@ -4203,7 +4203,7 @@ resource "aws_db_instance" "test" { # validation error). maintenance_window = "Fri:09:00-Fri:09:30" } -`)) +`) } func testAccInstanceConfig_namePrefix(identifierPrefix string) string { diff --git a/internal/service/rds/verify.go b/internal/service/rds/verify.go index 11ec581641e..c7df67724dc 100644 --- a/internal/service/rds/verify.go +++ b/internal/service/rds/verify.go @@ -1,8 +1,6 @@ package rds import ( - "fmt" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -15,10 +13,7 @@ func compareActualEngineVersion(d *schema.ResourceData, oldVersion string, newVe if oldVersion != newVersion && string(append([]byte(oldVersion), []byte(".")...)) != newVersionSubstr { d.Set("engine_version", newVersion) - fmt.Printf("[READ/cluster] engine_version: %s\n", newVersion) } d.Set("engine_version_actual", newVersion) - fmt.Printf("[READ/cluster] engine_version_actual: %s\n", newVersion) - } From bd7bdd783370b2f0bf5af606d8d86b818a8aee54 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Thu, 10 Mar 2022 17:49:26 -0500 Subject: [PATCH 200/229] Fix additional tests --- internal/service/rds/cluster_instance_test.go | 6 +- internal/service/rds/cluster_test.go | 48 +++++--- .../rds/engine_version_data_source_test.go | 12 +- internal/service/rds/event_subscription.go | 4 +- internal/service/rds/global_cluster.go | 4 + internal/service/rds/global_cluster_test.go | 79 +++++++----- .../service/rds/instance_data_source_test.go | 113 +++++++++++------- internal/service/rds/wait.go | 13 +- 8 files changed, 171 insertions(+), 108 deletions(-) diff --git a/internal/service/rds/cluster_instance_test.go b/internal/service/rds/cluster_instance_test.go index 649138ddf61..d688a4a6f6d 100644 --- a/internal/service/rds/cluster_instance_test.go +++ b/internal/service/rds/cluster_instance_test.go @@ -656,7 +656,7 @@ func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyIDAuroraMySQL1_defaultKe }, { Config: testAccClusterInstancePerformanceInsightsKMSKeyIdAuroraMySQL1Config(rName, engine), - ExpectError: regexp.MustCompile(`InvalidParameterCombination: You cannot change your Performance Insights KMS key`), + ExpectError: regexp.MustCompile(`InvalidParameterCombination: You .* change your Performance Insights KMS key`), }, }, }) @@ -728,7 +728,7 @@ func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyIDAuroraMySQL2_defaultKe }, { Config: testAccClusterInstancePerformanceInsightsKMSKeyIdAuroraMySQL2Config(rName, engine, engineVersion), - ExpectError: regexp.MustCompile(`InvalidParameterCombination: You cannot change your Performance Insights KMS key`), + ExpectError: regexp.MustCompile(`InvalidParameterCombination: You .* change your Performance Insights KMS key`), }, }, }) @@ -838,7 +838,7 @@ func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyIDAuroraPostgresql_defau }, { Config: testAccClusterInstancePerformanceInsightsKMSKeyIdAuroraPostgresqlConfig(rName, engine), - ExpectError: regexp.MustCompile(`InvalidParameterCombination: You cannot change your Performance Insights KMS key`), + ExpectError: regexp.MustCompile(`InvalidParameterCombination: You .* change your Performance Insights KMS key`), }, }, }) diff --git a/internal/service/rds/cluster_test.go b/internal/service/rds/cluster_test.go index 0ac9a15bc8a..d0abe29c25e 100644 --- a/internal/service/rds/cluster_test.go +++ b/internal/service/rds/cluster_test.go @@ -91,8 +91,8 @@ func TestAccRDSCluster_allowMajorVersionUpgrade(t *testing.T) { // either by having a new data source created or implementing the testing similar // to TestAccAWSDmsReplicationInstance_EngineVersion engine := "aurora-postgresql" - engineVersion1 := "10.11" - engineVersion2 := "11.7" + engineVersion1 := "12.9" + engineVersion2 := "13.5" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -144,8 +144,8 @@ func TestAccRDSCluster_allowMajorVersionUpgradeWithCustomParametersApplyImm(t *t // either by having a new data source created or implementing the testing similar // to TestAccAWSDmsReplicationInstance_EngineVersion engine := "aurora-postgresql" - engineVersion1 := "11.9" - engineVersion2 := "12.4" + engineVersion1 := "12.9" + engineVersion2 := "13.5" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -183,8 +183,8 @@ func TestAccRDSCluster_allowMajorVersionUpgradeWithCustomParameters(t *testing.T // either by having a new data source created or implementing the testing similar // to TestAccAWSDmsReplicationInstance_EngineVersion engine := "aurora-postgresql" - engineVersion1 := "10.11" - engineVersion2 := "11.7" + engineVersion1 := "12.9" + engineVersion2 := "13.5" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -1242,7 +1242,7 @@ func TestAccRDSCluster_GlobalClusterIdentifier_secondaryClustersWriteForwarding( func TestAccRDSCluster_port(t *testing.T) { var dbCluster1, dbCluster2 rds.DBCluster - rInt := sdkacctest.RandInt() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_cluster.test" resource.ParallelTest(t, resource.TestCase{ @@ -1252,14 +1252,14 @@ func TestAccRDSCluster_port(t *testing.T) { CheckDestroy: testAccCheckClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccClusterConfig_Port(rInt, 5432), + Config: testAccClusterConfig_Port(rName, 5432), Check: resource.ComposeTestCheckFunc( testAccCheckClusterExists(resourceName, &dbCluster1), resource.TestCheckResourceAttr(resourceName, "port", "5432"), ), }, { - Config: testAccClusterConfig_Port(rInt, 2345), + Config: testAccClusterConfig_Port(rName, 2345), Check: resource.ComposeTestCheckFunc( testAccCheckClusterExists(resourceName, &dbCluster2), resource.TestCheckResourceAttr(resourceName, "port", "2345"), @@ -2595,7 +2595,7 @@ func testAccClusterConfig_EngineVersion(upgrade bool, rInt int) string { return fmt.Sprintf(` data "aws_rds_engine_version" "test" { engine = "aurora-postgresql" - preferred_versions = ["9.6.3", "9.6.6", "9.6.8"] + preferred_versions = ["11.6", "11.7", "11.9"] } data "aws_rds_engine_version" "upgrade" { @@ -2666,19 +2666,19 @@ resource "aws_rds_cluster_instance" "test" { `, upgrade, rInt) } -func testAccClusterConfig_Port(rInt, port int) string { +func testAccClusterConfig_Port(rName string, port int) string { return fmt.Sprintf(` resource "aws_rds_cluster" "test" { - cluster_identifier = "tf-acc-test-%d" + cluster_identifier = %[1]q database_name = "mydb" - db_cluster_parameter_group_name = "default.aurora-postgresql11" + db_cluster_parameter_group_name = "default.aurora-postgresql13" engine = "aurora-postgresql" master_password = "mustbeeightcharaters" master_username = "foo" - port = %d + port = %[2]d skip_final_snapshot = true } -`, rInt, port) +`, rName, port) } func testAccClusterIncludingIAMRolesConfig(n int) string { @@ -3182,7 +3182,7 @@ func testAccClusterConfig_GlobalClusterIdentifier_EngineMode_Provisioned(rName s return fmt.Sprintf(` resource "aws_rds_global_cluster" "test" { engine = "aurora-postgresql" - engine_version = "10.11" + engine_version = "12.9" global_cluster_identifier = %[1]q } @@ -3409,10 +3409,20 @@ data "aws_availability_zones" "alternate" { } } +data "aws_rds_engine_version" "default" { + engine = "aurora-postgresql" +} + +data "aws_rds_orderable_db_instance" "test" { + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + preferred_instance_classes = ["db.r5.large", "db.r5.xlarge", "db.r6g.large"] # Aurora global db may be limited to rx +} + resource "aws_rds_global_cluster" "test" { global_cluster_identifier = %[1]q - engine = "aurora-postgresql" - engine_version = "10.11" + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version } resource "aws_rds_cluster" "primary" { @@ -3431,7 +3441,7 @@ resource "aws_rds_cluster_instance" "primary" { engine = aws_rds_cluster.primary.engine engine_version = aws_rds_cluster.primary.engine_version identifier = "%[1]s-primary" - instance_class = "db.r4.large" # only db.r4 or db.r5 are valid for Aurora global db + instance_class = data.aws_rds_orderable_db_instance.test.instance_class } resource "aws_vpc" "alternate" { diff --git a/internal/service/rds/engine_version_data_source_test.go b/internal/service/rds/engine_version_data_source_test.go index 83189f55c7c..26d76153ca6 100644 --- a/internal/service/rds/engine_version_data_source_test.go +++ b/internal/service/rds/engine_version_data_source_test.go @@ -81,7 +81,7 @@ func TestAccRDSEngineVersionDataSource_preferred(t *testing.T) { { Config: testAccEngineVersionPreferredDataSourceConfig(), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "version", "5.7.19"), + resource.TestCheckResourceAttr(dataSourceName, "version", "8.0.27"), ), }, }, @@ -129,9 +129,9 @@ func testAccEngineVersionPreCheck(t *testing.T) { func testAccEngineVersionBasicDataSourceConfig(engine, version, paramGroup string) string { return fmt.Sprintf(` data "aws_rds_engine_version" "test" { - engine = %q - version = %q - parameter_group_family = %q + engine = %[1]q + version = %[2]q + parameter_group_family = %[3]q } `, engine, version, paramGroup) } @@ -140,7 +140,7 @@ func testAccEngineVersionUpgradeTargetsDataSourceConfig() string { return ` data "aws_rds_engine_version" "test" { engine = "mysql" - version = "5.7.17" + version = "8.0.27" } ` } @@ -149,7 +149,7 @@ func testAccEngineVersionPreferredDataSourceConfig() string { return ` data "aws_rds_engine_version" "test" { engine = "mysql" - preferred_versions = ["85.9.12", "5.7.19", "5.7.17"] + preferred_versions = ["85.9.12", "8.0.27", "8.0.26"] } ` } diff --git a/internal/service/rds/event_subscription.go b/internal/service/rds/event_subscription.go index 4b45d79ee36..5b5711d5b5c 100644 --- a/internal/service/rds/event_subscription.go +++ b/internal/service/rds/event_subscription.go @@ -193,9 +193,7 @@ func resourceEventSubscriptionUpdate(d *schema.ResourceData, meta interface{}) e SubscriptionName: aws.String(d.Id()), } - if d.HasChange("enabled") { - input.Enabled = aws.Bool(d.Get("enabled").(bool)) - } + input.Enabled = aws.Bool(d.Get("enabled").(bool)) if d.HasChange("event_categories") { input.EventCategories = flex.ExpandStringSet(d.Get("event_categories").(*schema.Set)) diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index 28bd6004fec..5032a90cb7b 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -563,6 +563,10 @@ func resourceGlobalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, return resource.RetryableError(err) } + if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "Invalid database cluster identifier") { + return resource.RetryableError(err) + } + if tfawserr.ErrMessageContains(err, rds.ErrCodeInvalidDBClusterStateFault, "Cannot modify engine version without a primary instance in DB cluster") { return resource.NonRetryableError(err) } diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index ffb72cf43ec..db9c725e3f0 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -183,10 +183,10 @@ func TestAccRDSGlobalCluster_EngineVersion_aurora(t *testing.T) { CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalClusterEngineVersionConfig(rName, "aurora", "5.6.10a"), + Config: testAccGlobalClusterEngineVersionConfig(rName, "aurora"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.6.10a"), + resource.TestCheckResourceAttrPair(resourceName, "engine_version", "data.aws_rds_engine_version.default", "version"), ), }, { @@ -210,17 +210,17 @@ func TestAccRDSGlobalCluster_engineVersionUpdateMinor(t *testing.T) { CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-mysql", "5.7.mysql_aurora.2.10.1"), + Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-postgresql", "13.4"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), ), }, { - Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-mysql", "5.7.mysql_aurora.2.10.2"), + Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-postgresql", "13.5"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster2), testAccCheckGlobalClusterNotRecreated(&globalCluster1, &globalCluster2), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.7.mysql_aurora.2.10.2"), + resource.TestCheckResourceAttr(resourceName, "engine_version", "13.5"), ), }, { @@ -244,18 +244,17 @@ func TestAccRDSGlobalCluster_engineVersionUpdateMajor(t *testing.T) { CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.7.mysql_aurora.2.10.2"), + Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.6.mysql_aurora.1.23.4"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), ), }, { - Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "8.0.mysql_aurora.3.01.0"), - ExpectNonEmptyPlan: true, + Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-mysql", "5.7.mysql_aurora.2.10.2"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster2), testAccCheckGlobalClusterNotRecreated(&globalCluster1, &globalCluster2), - resource.TestCheckResourceAttr(resourceName, "engine_version", "8.0.mysql_aurora.3.01.0"), + resource.TestCheckResourceAttr(resourceName, "engine_version", "5.7.mysql_aurora.2.10.2"), ), }, { @@ -279,10 +278,10 @@ func TestAccRDSGlobalCluster_EngineVersion_auroraMySQL(t *testing.T) { CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalClusterEngineVersionConfig(rName, "aurora-mysql", "5.7.mysql_aurora.2.07.1"), + Config: testAccGlobalClusterEngineVersionConfig(rName, "aurora-mysql"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.7.mysql_aurora.2.07.1"), + resource.TestCheckResourceAttrPair(resourceName, "engine_version", "data.aws_rds_engine_version.default", "version"), ), }, { @@ -306,10 +305,10 @@ func TestAccRDSGlobalCluster_EngineVersion_auroraPostgresql(t *testing.T) { CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalClusterEngineVersionConfig(rName, "aurora-postgresql", "10.11"), + Config: testAccGlobalClusterEngineVersionConfig(rName, "aurora-postgresql"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), - resource.TestCheckResourceAttr(resourceName, "engine_version", "10.11"), + resource.TestCheckResourceAttrPair(resourceName, "engine_version", "data.aws_rds_engine_version.default", "version"), ), }, { @@ -564,35 +563,47 @@ resource "aws_rds_global_cluster" "test" { `, engine, rName) } -func testAccGlobalClusterEngineVersionConfig(rName, engine, engineVersion string) string { +func testAccGlobalClusterEngineVersionConfig(rName, engine string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = %[1]q +} + resource "aws_rds_global_cluster" "test" { - engine = %[1]q - engine_version = %[2]q - global_cluster_identifier = %[3]q + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + global_cluster_identifier = %[2]q } -`, engine, engineVersion, rName) +`, engine, rName) } func testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, engine, engineVersion string) string { return fmt.Sprintf(` +data "aws_rds_orderable_db_instance" "test" { + engine = %[1]q + engine_version = %[2]q + preferred_instance_classes = ["db.r5.large", "db.r5.xlarge", "db.r6g.large"] # Aurora global db may be limited to rx +} + resource "aws_rds_global_cluster" "test" { - engine = %[1]q - engine_version = %[2]q + engine = data.aws_rds_orderable_db_instance.test.engine + engine_version = data.aws_rds_orderable_db_instance.test.engine_version global_cluster_identifier = %[3]q } +// checkout the newly working global cluster stuff in cluster + resource "aws_rds_cluster" "test" { apply_immediately = true allow_major_version_upgrade = true cluster_identifier = %[3]q - engine = %[1]q - engine_version = %[2]q + engine = data.aws_rds_orderable_db_instance.test.engine + engine_version = data.aws_rds_orderable_db_instance.test.engine_version master_password = "mustbeeightcharacters" master_username = "test" skip_final_snapshot = true - global_cluster_identifier = aws_rds_global_cluster.test.global_cluster_identifier + global_cluster_identifier = aws_rds_global_cluster.test.id lifecycle { ignore_changes = [global_cluster_identifier] @@ -602,10 +613,10 @@ resource "aws_rds_cluster" "test" { resource "aws_rds_cluster_instance" "test" { apply_immediately = true cluster_identifier = aws_rds_cluster.test.id - engine = %[1]q - engine_version = %[2]q + engine = data.aws_rds_orderable_db_instance.test.engine + engine_version = data.aws_rds_orderable_db_instance.test.engine_version identifier = %[3]q - instance_class = "db.r3.large" + instance_class = data.aws_rds_orderable_db_instance.test.instance_class lifecycle { ignore_changes = [engine_version] @@ -616,10 +627,14 @@ resource "aws_rds_cluster_instance" "test" { func testAccGlobalClusterSourceClusterIdentifierConfig(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "aurora-postgresql" +} + resource "aws_rds_cluster" "test" { cluster_identifier = %[1]q - engine = "aurora-postgresql" - engine_version = "10.11" # Minimum supported version for Global Clusters + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version master_password = "mustbeeightcharacters" master_username = "test" skip_final_snapshot = true @@ -641,10 +656,14 @@ resource "aws_rds_global_cluster" "test" { func testAccGlobalClusterSourceClusterIdentifierStorageEncryptedConfig(rName string) string { return fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "aurora-postgresql" +} + resource "aws_rds_cluster" "test" { cluster_identifier = %[1]q - engine = "aurora-postgresql" - engine_version = "10.11" # Minimum supported version for Global Clusters + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version master_password = "mustbeeightcharacters" master_username = "test" skip_final_snapshot = true diff --git a/internal/service/rds/instance_data_source_test.go b/internal/service/rds/instance_data_source_test.go index 832f18ae86e..bbedf381724 100644 --- a/internal/service/rds/instance_data_source_test.go +++ b/internal/service/rds/instance_data_source_test.go @@ -12,6 +12,7 @@ import ( func TestAccRDSInstanceDataSource_basic(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + dataSourceName := "data.aws_db_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -21,23 +22,23 @@ func TestAccRDSInstanceDataSource_basic(t *testing.T) { { Config: testAccInstanceDataSourceConfig(rName), Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "address"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "allocated_storage"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "auto_minor_version_upgrade"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "db_instance_class"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "db_name"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "db_subnet_group"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "endpoint"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "engine"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "hosted_zone_id"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "master_username"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "port"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "multi_az"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "enabled_cloudwatch_logs_exports.0"), - resource.TestCheckResourceAttrSet("data.aws_db_instance.bar", "enabled_cloudwatch_logs_exports.1"), - resource.TestCheckResourceAttrPair("data.aws_db_instance.bar", "resource_id", "aws_db_instance.bar", "resource_id"), - resource.TestCheckResourceAttrPair("data.aws_db_instance.bar", "tags.%", "aws_db_instance.bar", "tags.%"), - resource.TestCheckResourceAttrPair("data.aws_db_instance.bar", "tags.Environment", "aws_db_instance.bar", "tags.Environment"), + resource.TestCheckResourceAttrSet(dataSourceName, "address"), + resource.TestCheckResourceAttrSet(dataSourceName, "allocated_storage"), + resource.TestCheckResourceAttrSet(dataSourceName, "auto_minor_version_upgrade"), + resource.TestCheckResourceAttrSet(dataSourceName, "db_instance_class"), + resource.TestCheckResourceAttrSet(dataSourceName, "db_name"), + resource.TestCheckResourceAttrSet(dataSourceName, "db_subnet_group"), + resource.TestCheckResourceAttrSet(dataSourceName, "endpoint"), + resource.TestCheckResourceAttrSet(dataSourceName, "engine"), + resource.TestCheckResourceAttrSet(dataSourceName, "hosted_zone_id"), + resource.TestCheckResourceAttrSet(dataSourceName, "master_username"), + resource.TestCheckResourceAttrSet(dataSourceName, "port"), + resource.TestCheckResourceAttrSet(dataSourceName, "multi_az"), + resource.TestCheckResourceAttrSet(dataSourceName, "enabled_cloudwatch_logs_exports.0"), + resource.TestCheckResourceAttrSet(dataSourceName, "enabled_cloudwatch_logs_exports.1"), + resource.TestCheckResourceAttrPair(dataSourceName, "resource_id", "aws_db_instance.test", "resource_id"), + resource.TestCheckResourceAttrPair(dataSourceName, "tags.%", "aws_db_instance.test", "tags.%"), + resource.TestCheckResourceAttrPair(dataSourceName, "tags.Environment", "aws_db_instance.test", "tags.Environment"), ), }, }, @@ -46,6 +47,7 @@ func TestAccRDSInstanceDataSource_basic(t *testing.T) { func TestAccRDSInstanceDataSource_ec2Classic(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + dataSourceName := "data.aws_db_instance.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); acctest.PreCheckEC2Classic(t) }, @@ -55,7 +57,7 @@ func TestAccRDSInstanceDataSource_ec2Classic(t *testing.T) { { Config: testAccInstanceDataSourceConfig_ec2Classic(rName), Check: resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr("data.aws_db_instance.bar", "db_subnet_group", ""), + resource.TestCheckResourceAttr(dataSourceName, "db_subnet_group", ""), ), }, }, @@ -63,24 +65,47 @@ func TestAccRDSInstanceDataSource_ec2Classic(t *testing.T) { } func testAccInstanceDataSourceConfig(rName string) string { - return fmt.Sprintf(` -data "aws_rds_orderable_db_instance" "test" { - engine = "mariadb" - preferred_instance_classes = ["db.t3.micro", "db.t2.micro", "db.t3.small"] + return acctest.ConfigCompose( + testAccInstanceConfig_orderableClassMariadb(), + acctest.ConfigAvailableAZsNoOptIn(), + fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" + + tags = { + Name = %[1]q + } } -resource "aws_db_instance" "bar" { - identifier = %[1]q +resource "aws_subnet" "test" { + count = 2 - allocated_storage = 10 - engine = data.aws_rds_orderable_db_instance.test.engine - instance_class = data.aws_rds_orderable_db_instance.test.instance_class - name = "baz" - password = "barbarbarbar" - username = "foo" + availability_zone = data.aws_availability_zones.available.names[count.index] + cidr_block = "10.0.${count.index}.0/24" + vpc_id = aws_vpc.test.id + tags = { + Name = %[1]q + } +} + +resource "aws_db_subnet_group" "test" { + name = %[1]q + subnet_ids = aws_subnet.test[*].id +} + +resource "aws_db_instance" "test" { + allocated_storage = 10 backup_retention_period = 0 + db_subnet_group_name = aws_db_subnet_group.test.name + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + identifier = %[1]q + instance_class = data.aws_rds_orderable_db_instance.test.instance_class + name = "baz" + password = "barbarbarbar" skip_final_snapshot = true + username = "foo" enabled_cloudwatch_logs_exports = [ "audit", @@ -92,39 +117,45 @@ resource "aws_db_instance" "bar" { } } -data "aws_db_instance" "bar" { - db_instance_identifier = aws_db_instance.bar.identifier +data "aws_db_instance" "test" { + db_instance_identifier = aws_db_instance.test.identifier } -`, rName) +`, rName)) } func testAccInstanceDataSourceConfig_ec2Classic(rName string) string { return acctest.ConfigCompose( acctest.ConfigEC2ClassicRegionProvider(), fmt.Sprintf(` +data "aws_rds_engine_version" "default" { + engine = "mysql" +} + +# EC2-Classic specific data "aws_rds_orderable_db_instance" "test" { - engine = "mysql" - engine_version = "8.0.25" - preferred_instance_classes = ["db.t2.micro", "db.m3.medium", "db.m3.large", "db.r3.large"] + engine = data.aws_rds_engine_version.default.engine + engine_version = data.aws_rds_engine_version.default.version + preferred_instance_classes = ["db.m3.medium", "db.m3.large", "db.r3.large"] } -resource "aws_db_instance" "bar" { +resource "aws_db_instance" "test" { identifier = %[1]q allocated_storage = 10 engine = data.aws_rds_orderable_db_instance.test.engine engine_version = data.aws_rds_orderable_db_instance.test.engine_version instance_class = data.aws_rds_orderable_db_instance.test.instance_class - name = "baz" + storage_type = data.aws_rds_orderable_db_instance.test.storage_type + db_name = "baz" password = "barbarbarbar" username = "foo" publicly_accessible = true security_group_names = ["default"] - parameter_group_name = "default.mysql8.0" + parameter_group_name = "default.${data.aws_rds_engine_version.default.parameter_group_family}" skip_final_snapshot = true } -data "aws_db_instance" "bar" { - db_instance_identifier = aws_db_instance.bar.identifier +data "aws_db_instance" "test" { + db_instance_identifier = aws_db_instance.test.identifier } `, rName)) } diff --git a/internal/service/rds/wait.go b/internal/service/rds/wait.go index 2edd2eb0326..c55a9ac8399 100644 --- a/internal/service/rds/wait.go +++ b/internal/service/rds/wait.go @@ -54,12 +54,13 @@ func waitEventSubscriptionDeleted(conn *rds.RDS, id string, timeout time.Duratio func waitEventSubscriptionUpdated(conn *rds.RDS, id string, timeout time.Duration) (*rds.EventSubscription, error) { stateConf := &resource.StateChangeConf{ - Pending: []string{EventSubscriptionStatusModifying}, - Target: []string{EventSubscriptionStatusActive}, - Refresh: statusEventSubscription(conn, id), - Timeout: timeout, - MinTimeout: 10 * time.Second, - Delay: 30 * time.Second, + Pending: []string{EventSubscriptionStatusModifying}, + Target: []string{EventSubscriptionStatusActive}, + Refresh: statusEventSubscription(conn, id), + Timeout: timeout, + MinTimeout: 10 * time.Second, + Delay: 30 * time.Second, + ContinuousTargetOccurence: 2, } outputRaw, err := stateConf.WaitForState() From 904b06b8e3024b7baba618170f69df2a9fc95adf Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Thu, 10 Mar 2022 20:45:22 -0500 Subject: [PATCH 201/229] rds: Fix additional issues --- .changelog/23560.txt | 11 +++ internal/service/rds/cluster.go | 6 +- internal/service/rds/cluster_endpoint.go | 12 +-- internal/service/rds/global_cluster.go | 92 ++++++++++++------- internal/service/rds/global_cluster_test.go | 4 +- internal/service/rds/wait.go | 2 +- .../docs/r/rds_global_cluster.html.markdown | 9 ++ 7 files changed, 92 insertions(+), 44 deletions(-) create mode 100644 .changelog/23560.txt diff --git a/.changelog/23560.txt b/.changelog/23560.txt new file mode 100644 index 00000000000..ad9eaf3f32f --- /dev/null +++ b/.changelog/23560.txt @@ -0,0 +1,11 @@ +```release-note:bug +resource/aws_rds_event_subscription: Fix issue where `enabled` was sometimes not updated +``` + +```release-note:bug +resource/aws_db_instance: Fix issues where configured update timeout was not respected, and update would fail if instance were in the process of being configured. +``` + +```release-note:bug +resource/aws_rds_global_cluster: Fix in-place DB Cluster minor version upgrade error: "Invalid database cluster identifier" +``` \ No newline at end of file diff --git a/internal/service/rds/cluster.go b/internal/service/rds/cluster.go index 4836782c5bd..681a403b00b 100644 --- a/internal/service/rds/cluster.go +++ b/internal/service/rds/cluster.go @@ -990,7 +990,7 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { } log.Printf("[INFO] Waiting for RDS Cluster (%s) to be available", d.Id()) - err = waitForRDSClusterUpdate(conn, d.Id(), d.Timeout(schema.TimeoutCreate)) + err = waitForClusterUpdate(conn, d.Id(), d.Timeout(schema.TimeoutCreate)) if err != nil { return fmt.Errorf("error waiting for RDS Cluster (%s) to be available: %s", d.Id(), err) } @@ -1288,7 +1288,7 @@ func resourceClusterUpdate(d *schema.ResourceData, meta interface{}) error { } log.Printf("[INFO] Waiting for RDS Cluster (%s) to be available", d.Id()) - err = waitForRDSClusterUpdate(conn, d.Id(), d.Timeout(schema.TimeoutUpdate)) + err = waitForClusterUpdate(conn, d.Id(), d.Timeout(schema.TimeoutUpdate)) if err != nil { return fmt.Errorf("error waiting for RDS Cluster (%s) to be available: %s", d.Id(), err) } @@ -1506,7 +1506,7 @@ var resourceClusterUpdatePendingStates = []string{ "upgrading", } -func waitForRDSClusterUpdate(conn *rds.RDS, id string, timeout time.Duration) error { +func waitForClusterUpdate(conn *rds.RDS, id string, timeout time.Duration) error { stateConf := &resource.StateChangeConf{ Pending: resourceClusterUpdatePendingStates, Target: []string{"available"}, diff --git a/internal/service/rds/cluster_endpoint.go b/internal/service/rds/cluster_endpoint.go index 805303b1b1f..bdf9beed532 100644 --- a/internal/service/rds/cluster_endpoint.go +++ b/internal/service/rds/cluster_endpoint.go @@ -18,9 +18,9 @@ import ( ) const ( - AWSRDSClusterEndpointCreateTimeout = 30 * time.Minute - AWSRDSClusterEndpointRetryDelay = 5 * time.Second - ClusterEndpointRetryMinTimeout = 3 * time.Second + clusterEndpointCreateTimeout = 30 * time.Minute + clusterEndpointRetryDelay = 5 * time.Second + ClusterEndpointRetryMinTimeout = 3 * time.Second ) func ResourceClusterEndpoint() *schema.Resource { @@ -114,7 +114,7 @@ func resourceClusterEndpointCreate(d *schema.ResourceData, meta interface{}) err d.SetId(endpointId) - err = resourceClusterEndpointWaitForAvailable(AWSRDSClusterEndpointCreateTimeout, d.Id(), conn) + err = resourceClusterEndpointWaitForAvailable(clusterEndpointCreateTimeout, d.Id(), conn) if err != nil { return err } @@ -252,7 +252,7 @@ func resourceClusterEndpointWaitForDestroy(timeout time.Duration, id string, con Target: []string{"destroyed"}, Refresh: DBClusterEndpointStateRefreshFunc(conn, id), Timeout: timeout, - Delay: AWSRDSClusterEndpointRetryDelay, + Delay: clusterEndpointRetryDelay, MinTimeout: ClusterEndpointRetryMinTimeout, } _, err := stateConf.WaitForState() @@ -270,7 +270,7 @@ func resourceClusterEndpointWaitForAvailable(timeout time.Duration, id string, c Target: []string{"available"}, Refresh: DBClusterEndpointStateRefreshFunc(conn, id), Timeout: timeout, - Delay: AWSRDSClusterEndpointRetryDelay, + Delay: clusterEndpointRetryDelay, MinTimeout: ClusterEndpointRetryMinTimeout, } diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index 5032a90cb7b..994b8f2c46b 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -3,8 +3,10 @@ package rds import ( "fmt" "log" + "strings" "time" + "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/rds" "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" @@ -16,7 +18,9 @@ import ( ) const ( - rdsGlobalClusterRemovalTimeout = 2 * time.Minute + GlobalClusterRemovalTimeout = 30 * time.Minute + globalClusterCreateTimeout = 30 * time.Minute + globalClusterUpdateTimeout = 30 * time.Minute ) func ResourceGlobalCluster() *schema.Resource { @@ -29,6 +33,12 @@ func ResourceGlobalCluster() *schema.Resource { State: schema.ImportStatePassthrough, }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(globalClusterCreateTimeout), + Update: schema.DefaultTimeout(globalClusterUpdateTimeout), + Delete: schema.DefaultTimeout(GlobalClusterRemovalTimeout), + }, + Schema: map[string]*schema.Schema{ "arn": { Type: schema.TypeString, @@ -153,7 +163,7 @@ func resourceGlobalClusterCreate(d *schema.ResourceData, meta interface{}) error d.SetId(aws.StringValue(output.GlobalCluster.GlobalClusterIdentifier)) - if err := waitForGlobalClusterCreation(conn, d.Id()); err != nil { + if err := waitForGlobalClusterCreation(conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { return fmt.Errorf("error waiting for RDS Global Cluster (%s) availability: %s", d.Id(), err) } @@ -213,7 +223,7 @@ func resourceGlobalClusterUpdate(d *schema.ResourceData, meta interface{}) error } if d.HasChange("engine_version") { - if err := resourceGlobalClusterUpgradeEngineVersion(d, conn); err != nil { + if err := globalClusterUpgradeEngineVersion(d, conn); err != nil { return err } } @@ -229,14 +239,14 @@ func resourceGlobalClusterUpdate(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("error deleting RDS Global Cluster: %s", err) } - if err := waitForGlobalClusterUpdate(conn, d.Id()); err != nil { + if err := waitForGlobalClusterUpdate(conn, d.Id(), d.Timeout(schema.TimeoutUpdate)); err != nil { return fmt.Errorf("error waiting for RDS Global Cluster (%s) update: %s", d.Id(), err) } return resourceGlobalClusterRead(d, meta) } -func resourceGlobalClusterGetIdByARN(conn *rds.RDS, arn string) string { +func globalClusterGetIDByARN(conn *rds.RDS, arn string) string { result, err := conn.DescribeDBClusters(&rds.DescribeDBClustersInput{}) if err != nil { return "" @@ -281,7 +291,7 @@ func resourceGlobalClusterDelete(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("error removing RDS DB Cluster (%s) from Global Cluster (%s): %w", dbClusterArn, d.Id(), err) } - if err := waitForGlobalClusterRemoval(conn, dbClusterArn); err != nil { + if err := waitForGlobalClusterRemoval(conn, dbClusterArn, d.Timeout(schema.TimeoutDelete)); err != nil { return fmt.Errorf("error waiting for RDS DB Cluster (%s) removal from RDS Global Cluster (%s): %w", dbClusterArn, d.Id(), err) } } @@ -295,7 +305,7 @@ func resourceGlobalClusterDelete(d *schema.ResourceData, meta interface{}) error // Allow for eventual consistency // InvalidGlobalClusterStateFault: Global Cluster arn:aws:rds::123456789012:global-cluster:tf-acc-test-5618525093076697001-0 is not empty - err := resource.Retry(1*time.Minute, func() *resource.RetryError { + err := resource.Retry(d.Timeout(schema.TimeoutDelete), func() *resource.RetryError { _, err := conn.DeleteGlobalCluster(input) if tfawserr.ErrMessageContains(err, rds.ErrCodeInvalidGlobalClusterStateFault, "is not empty") { @@ -321,7 +331,7 @@ func resourceGlobalClusterDelete(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("error deleting RDS Global Cluster: %s", err) } - if err := WaitForGlobalClusterDeletion(conn, d.Id()); err != nil { + if err := WaitForGlobalClusterDeletion(conn, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil { return fmt.Errorf("error waiting for RDS Global Cluster (%s) deletion: %s", d.Id(), err) } @@ -414,7 +424,7 @@ func DescribeGlobalClusterFromClusterARN(conn *rds.RDS, dbClusterARN string) (*r return globalCluster, err } -func rdsGlobalClusterRefreshFunc(conn *rds.RDS, globalClusterID string) resource.StateRefreshFunc { +func globalClusterRefreshFunc(conn *rds.RDS, globalClusterID string) resource.StateRefreshFunc { return func() (interface{}, string, error) { globalCluster, err := DescribeGlobalCluster(conn, globalClusterID) @@ -434,12 +444,12 @@ func rdsGlobalClusterRefreshFunc(conn *rds.RDS, globalClusterID string) resource } } -func waitForGlobalClusterCreation(conn *rds.RDS, globalClusterID string) error { +func waitForGlobalClusterCreation(conn *rds.RDS, globalClusterID string, timeout time.Duration) error { stateConf := &resource.StateChangeConf{ Pending: []string{"creating"}, Target: []string{"available"}, - Refresh: rdsGlobalClusterRefreshFunc(conn, globalClusterID), - Timeout: 10 * time.Minute, + Refresh: globalClusterRefreshFunc(conn, globalClusterID), + Timeout: timeout, } log.Printf("[DEBUG] Waiting for RDS Global Cluster (%s) availability", globalClusterID) @@ -448,12 +458,12 @@ func waitForGlobalClusterCreation(conn *rds.RDS, globalClusterID string) error { return err } -func waitForGlobalClusterUpdate(conn *rds.RDS, globalClusterID string) error { +func waitForGlobalClusterUpdate(conn *rds.RDS, globalClusterID string, timeout time.Duration) error { stateConf := &resource.StateChangeConf{ Pending: []string{"modifying", "upgrading"}, Target: []string{"available"}, - Refresh: rdsGlobalClusterRefreshFunc(conn, globalClusterID), - Timeout: 10 * time.Minute, + Refresh: globalClusterRefreshFunc(conn, globalClusterID), + Timeout: timeout, Delay: 30 * time.Second, } @@ -463,15 +473,15 @@ func waitForGlobalClusterUpdate(conn *rds.RDS, globalClusterID string) error { return err } -func WaitForGlobalClusterDeletion(conn *rds.RDS, globalClusterID string) error { +func WaitForGlobalClusterDeletion(conn *rds.RDS, globalClusterID string, timeout time.Duration) error { stateConf := &resource.StateChangeConf{ Pending: []string{ "available", "deleting", }, Target: []string{"deleted"}, - Refresh: rdsGlobalClusterRefreshFunc(conn, globalClusterID), - Timeout: 10 * time.Minute, + Refresh: globalClusterRefreshFunc(conn, globalClusterID), + Timeout: timeout, NotFoundChecks: 1, } @@ -485,11 +495,11 @@ func WaitForGlobalClusterDeletion(conn *rds.RDS, globalClusterID string) error { return err } -func waitForGlobalClusterRemoval(conn *rds.RDS, dbClusterIdentifier string) error { +func waitForGlobalClusterRemoval(conn *rds.RDS, dbClusterIdentifier string, timeout time.Duration) error { var globalCluster *rds.GlobalCluster stillExistsErr := fmt.Errorf("RDS DB Cluster still exists in RDS Global Cluster") - err := resource.Retry(rdsGlobalClusterRemovalTimeout, func() *resource.RetryError { + err := resource.Retry(timeout, func() *resource.RetryError { var err error globalCluster, err = DescribeGlobalClusterFromClusterARN(conn, dbClusterIdentifier) @@ -520,13 +530,13 @@ func waitForGlobalClusterRemoval(conn *rds.RDS, dbClusterIdentifier string) erro return nil } -func resourceGlobalClusterUpgradeMajorEngineVersion(clusterId string, engineVersion string, conn *rds.RDS) error { +func globalClusterUpgradeMajorEngineVersion(clusterId string, engineVersion string, conn *rds.RDS) error { input := &rds.ModifyGlobalClusterInput{ GlobalClusterIdentifier: aws.String(clusterId), } input.AllowMajorVersionUpgrade = aws.Bool(true) input.EngineVersion = aws.String(engineVersion) - err := resource.Retry(rdsClusterInitiateUpgradeTimeout, func() *resource.RetryError { + err := resource.Retry(clusterInitiateUpgradeTimeout, func() *resource.RetryError { _, err := conn.ModifyGlobalCluster(input) if err != nil { if tfawserr.ErrCodeEquals(err, rds.ErrCodeGlobalClusterNotFoundFault) { @@ -547,26 +557,42 @@ func resourceGlobalClusterUpgradeMajorEngineVersion(clusterId string, engineVers return err } -func resourceGlobalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, engineVersion string, conn *rds.RDS) error { +func globalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, engineVersion string, conn *rds.RDS) error { for _, clusterMemberRaw := range clusterMembers.List() { clusterMember := clusterMemberRaw.(map[string]interface{}) + if clusterMemberArn, ok := clusterMember["db_cluster_arn"]; ok && clusterMemberArn.(string) != "" { + parsedARN, err := arn.Parse(clusterMemberArn.(string)) + + if err != nil { + return fmt.Errorf("could not parse ARN while upgrading RDS Global Cluster minor engine version: %w", err) + } + + dbi := "" + + if parsedARN.Resource != "" { + parts := strings.Split(parsedARN.Resource, ":") + + if len(parts) < 2 { + return fmt.Errorf("could not get DB Cluster ID from parsing ARN while upgrading RDS Global Cluster minor engine version: %w", err) + } + + dbi = parts[1] + } + modInput := &rds.ModifyDBClusterInput{ ApplyImmediately: aws.Bool(true), - DBClusterIdentifier: aws.String(clusterMemberArn.(string)), + DBClusterIdentifier: aws.String(dbi), EngineVersion: aws.String(engineVersion), } - err := resource.Retry(rdsClusterInitiateUpgradeTimeout, func() *resource.RetryError { + + err = resource.Retry(clusterInitiateUpgradeTimeout, func() *resource.RetryError { _, err := conn.ModifyDBCluster(modInput) if err != nil { if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "IAM role ARN value is invalid or does not include the required permissions") { return resource.RetryableError(err) } - if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "Invalid database cluster identifier") { - return resource.RetryableError(err) - } - if tfawserr.ErrMessageContains(err, rds.ErrCodeInvalidDBClusterStateFault, "Cannot modify engine version without a primary instance in DB cluster") { return resource.NonRetryableError(err) } @@ -592,11 +618,11 @@ func resourceGlobalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, return nil } -func resourceGlobalClusterUpgradeEngineVersion(d *schema.ResourceData, conn *rds.RDS) error { +func globalClusterUpgradeEngineVersion(d *schema.ResourceData, conn *rds.RDS) error { log.Printf("[DEBUG] Upgrading RDS Global Cluster (%s) engine version: %s", d.Id(), d.Get("engine_version")) - err := resourceGlobalClusterUpgradeMajorEngineVersion(d.Id(), d.Get("engine_version").(string), conn) + err := globalClusterUpgradeMajorEngineVersion(d.Id(), d.Get("engine_version").(string), conn) if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "ModifyGlobalCluster only supports Major Version Upgrades. To patch the members of your global cluster to a newer minor version you need to call ModifyDbCluster in each one of them.") { - err = resourceGlobalClusterUpgradeMinorEngineVersion(d.Get("global_cluster_members").(*schema.Set), d.Get("engine_version").(string), conn) + err = globalClusterUpgradeMinorEngineVersion(d.Get("global_cluster_members").(*schema.Set), d.Get("engine_version").(string), conn) if err != nil { return err } @@ -608,7 +634,7 @@ func resourceGlobalClusterUpgradeEngineVersion(d *schema.ResourceData, conn *rds return err } for _, clusterMember := range globalCluster.GlobalClusterMembers { - err := waitForRDSClusterUpdate(conn, resourceGlobalClusterGetIdByARN(conn, aws.StringValue(clusterMember.DBClusterArn)), d.Timeout(schema.TimeoutUpdate)) + err := waitForClusterUpdate(conn, globalClusterGetIDByARN(conn, aws.StringValue(clusterMember.DBClusterArn)), d.Timeout(schema.TimeoutUpdate)) if err != nil { return err } diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index db9c725e3f0..638ada23f4c 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -210,12 +210,14 @@ func TestAccRDSGlobalCluster_engineVersionUpdateMinor(t *testing.T) { CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { + //Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.6.mysql_aurora.1.22.2"), Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-postgresql", "13.4"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), ), }, { + //Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora", "5.6.mysql_aurora.1.23.2"), Config: testAccGlobalClusterWithPrimaryEngineVersionConfig(rName, "aurora-postgresql", "13.5"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster2), @@ -488,7 +490,7 @@ func testAccCheckGlobalClusterDisappears(globalCluster *rds.GlobalCluster) resou return err } - return tfrds.WaitForGlobalClusterDeletion(conn, aws.StringValue(globalCluster.GlobalClusterIdentifier)) + return tfrds.WaitForGlobalClusterDeletion(conn, aws.StringValue(globalCluster.GlobalClusterIdentifier), tfrds.GlobalClusterRemovalTimeout) } } diff --git a/internal/service/rds/wait.go b/internal/service/rds/wait.go index c55a9ac8399..096fe77f506 100644 --- a/internal/service/rds/wait.go +++ b/internal/service/rds/wait.go @@ -8,7 +8,7 @@ import ( ) const ( - rdsClusterInitiateUpgradeTimeout = 5 * time.Minute + clusterInitiateUpgradeTimeout = 5 * time.Minute dbClusterRoleAssociationCreatedTimeout = 5 * time.Minute dbClusterRoleAssociationDeletedTimeout = 5 * time.Minute diff --git a/website/docs/r/rds_global_cluster.html.markdown b/website/docs/r/rds_global_cluster.html.markdown index 48aa664fd2e..ad39c887419 100644 --- a/website/docs/r/rds_global_cluster.html.markdown +++ b/website/docs/r/rds_global_cluster.html.markdown @@ -187,6 +187,15 @@ In addition to all arguments above, the following attributes are exported: * `global_cluster_resource_id` - AWS Region-unique, immutable identifier for the global database cluster. This identifier is found in AWS CloudTrail log entries whenever the AWS KMS key for the DB cluster is accessed * `id` - RDS Global Cluster identifier +## Timeouts + +`aws_rds_global_cluster` provides the following +[Timeouts](https://www.terraform.io/docs/configuration/blocks/resources/syntax.html#operation-timeouts) configuration options: + +- `create` - (Default `30 minutes`) +- `update` - (Default `30 minutes`) +- `delete` - (Default `30 minutes`) + ## Import `aws_rds_global_cluster` can be imported by using the RDS Global Cluster identifier, e.g., From 4fa0778196f4f339a2047053edf4bd0aaee19788 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Thu, 10 Mar 2022 20:56:31 -0500 Subject: [PATCH 202/229] Update changelog --- .changelog/23560.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.changelog/23560.txt b/.changelog/23560.txt index ad9eaf3f32f..681fa41670f 100644 --- a/.changelog/23560.txt +++ b/.changelog/23560.txt @@ -8,4 +8,8 @@ resource/aws_db_instance: Fix issues where configured update timeout was not res ```release-note:bug resource/aws_rds_global_cluster: Fix in-place DB Cluster minor version upgrade error: "Invalid database cluster identifier" -``` \ No newline at end of file +``` + +```release-note:enhancement +resource/aws_rds_global_cluster: Add configurable timeouts +``` From 23bfced1578e24ed6174452e6eb5e274cd364165 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Thu, 10 Mar 2022 21:18:12 -0500 Subject: [PATCH 203/229] Add session to client --- internal/conns/conns.go | 2 + internal/service/rds/global_cluster_test.go | 103 +++++++++++++++++++- internal/service/rds/sweep.go | 2 +- 3 files changed, 103 insertions(+), 4 deletions(-) diff --git a/internal/conns/conns.go b/internal/conns/conns.go index e0658523a0b..db3f008434a 100644 --- a/internal/conns/conns.go +++ b/internal/conns/conns.go @@ -1141,6 +1141,7 @@ type AWSClient struct { ServiceDiscoveryConn *servicediscovery.ServiceDiscovery ServiceQuotasConn *servicequotas.ServiceQuotas SESConn *ses.SES + Session *session.Session SESV2Conn *sesv2.SESV2 SFNConn *sfn.SFN ShieldConn *shield.Shield @@ -1540,6 +1541,7 @@ func (c *Config) Client(ctx context.Context) (interface{}, diag.Diagnostics) { ServiceQuotasConn: servicequotas.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[ServiceQuotas])})), SESConn: ses.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[SES])})), SESV2Conn: sesv2.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[SESV2])})), + Session: sess, SFNConn: sfn.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[SFN])})), SignerConn: signer.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[Signer])})), SimpleDBConn: simpledb.New(sess.Copy(&aws.Config{Endpoint: aws.String(c.Endpoints[SimpleDB])})), diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index 638ada23f4c..4ab1dd98861 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" 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/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" @@ -198,7 +199,7 @@ func TestAccRDSGlobalCluster_EngineVersion_aurora(t *testing.T) { }) } -func TestAccRDSGlobalCluster_engineVersionUpdateMinor(t *testing.T) { +func TestAccRDSGlobalCluster_EngineVersion_updateMinor(t *testing.T) { var globalCluster1, globalCluster2 rds.GlobalCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_global_cluster.test" @@ -234,7 +235,7 @@ func TestAccRDSGlobalCluster_engineVersionUpdateMinor(t *testing.T) { }) } -func TestAccRDSGlobalCluster_engineVersionUpdateMajor(t *testing.T) { +func TestAccRDSGlobalCluster_EngineVersion_updateMajor(t *testing.T) { var globalCluster1, globalCluster2 rds.GlobalCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_global_cluster.test" @@ -268,6 +269,36 @@ func TestAccRDSGlobalCluster_engineVersionUpdateMajor(t *testing.T) { }) } +func TestAccRDSGlobalCluster_EngineVersion_updateMinorMultiRegion(t *testing.T) { + var providers []*schema.Provider + var globalCluster1, globalCluster2 rds.GlobalCluster + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_rds_global_cluster.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckGlobalCluster(t) }, + ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), + ProviderFactories: acctest.FactoriesAlternate(&providers), + CheckDestroy: testAccCheckGlobalClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGlobalClusterEngineVersionUpgradeMultiRegionConfig(rName, "aurora", "5.6.mysql_aurora.1.22.2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGlobalClusterExists(resourceName, &globalCluster1), + ), + }, + { + Config: testAccGlobalClusterEngineVersionUpgradeMultiRegionConfig(rName, "aurora", "5.6.mysql_aurora.1.23.2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGlobalClusterExists(resourceName, &globalCluster2), + testAccCheckGlobalClusterNotRecreated(&globalCluster1, &globalCluster2), + resource.TestCheckResourceAttr(resourceName, "engine_version", "5.6.mysql_aurora.1.23.2"), + ), + }, + }, + }) +} + func TestAccRDSGlobalCluster_EngineVersion_auroraMySQL(t *testing.T) { var globalCluster1 rds.GlobalCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -295,7 +326,7 @@ func TestAccRDSGlobalCluster_EngineVersion_auroraMySQL(t *testing.T) { }) } -func TestAccRDSGlobalCluster_EngineVersion_auroraPostgresql(t *testing.T) { +func TestAccRDSGlobalCluster_EngineVersion_auroraPostgreSQL(t *testing.T) { var globalCluster1 rds.GlobalCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_global_cluster.test" @@ -627,6 +658,72 @@ resource "aws_rds_cluster_instance" "test" { `, engine, engineVersion, rName) } +func testAccGlobalClusterEngineVersionUpgradeMultiRegionConfig(rName, engine, engineVersion string) string { + return acctest.ConfigCompose( + acctest.ConfigAlternateRegionProvider(), + fmt.Sprintf(` +resource "aws_rds_global_cluster" "test" { + engine = %[1]q + engine_version = %[2]q + global_cluster_identifier = %[3]q +} + +resource "aws_rds_cluster" "test" { + allow_major_version_upgrade = true + apply_immediately = true + cluster_identifier = %[3]q + database_name = "totoro" + engine = aws_rds_global_cluster.test.engine + engine_version = aws_rds_global_cluster.test.engine_version + global_cluster_identifier = aws_rds_global_cluster.test.global_cluster_identifier + master_password = "mustbeeightcharacters" + master_username = "test" + skip_final_snapshot = true + + lifecycle { + ignore_changes = [global_cluster_identifier] + } +} + +resource "aws_rds_cluster_instance" "test" { + apply_immediately = true + cluster_identifier = aws_rds_cluster.test.id + engine = aws_rds_global_cluster.test.engine + engine_version = aws_rds_global_cluster.test.engine_version + identifier = %[3]q + instance_class = "db.r3.large" +} + +resource "aws_rds_cluster" "test2" { + provider = "awsalternate" + + allow_major_version_upgrade = true + apply_immediately = true + cluster_identifier = "%[3]s-2" + engine = %[1]q + engine_version = %[2]q + global_cluster_identifier = aws_rds_global_cluster.test.global_cluster_identifier + replication_source_identifier = aws_rds_cluster.test.arn + skip_final_snapshot = true + + lifecycle { + ignore_changes = [global_cluster_identifier] + } +} + +resource "aws_rds_cluster_instance" "test2" { + provider = "awsalternate" + + apply_immediately = true + cluster_identifier = aws_rds_cluster.test2.id + engine = %[1]q + engine_version = %[2]q + identifier = "%[3]s-2" + instance_class = "db.r3.large" +} +`, engine, engineVersion, rName)) +} + func testAccGlobalClusterSourceClusterIdentifierConfig(rName string) string { return fmt.Sprintf(` data "aws_rds_engine_version" "default" { diff --git a/internal/service/rds/sweep.go b/internal/service/rds/sweep.go index 8997ecea70e..7af82b991bf 100644 --- a/internal/service/rds/sweep.go +++ b/internal/service/rds/sweep.go @@ -346,7 +346,7 @@ func sweepGlobalClusters(region string) error { continue } - if err := WaitForGlobalClusterDeletion(conn, id); err != nil { + if err := WaitForGlobalClusterDeletion(conn, id, 30*time.Minute); err != nil { log.Printf("[ERROR] Failure while waiting for RDS Global Cluster (%s) to be deleted: %s", id, err) } } From eadfece0a2e09d3ad405885b703521f7814304a6 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Thu, 10 Mar 2022 21:46:28 -0500 Subject: [PATCH 204/229] Glint in your eye --- internal/service/rds/global_cluster.go | 30 +++++++++++++++------ internal/service/rds/global_cluster_test.go | 2 +- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index 994b8f2c46b..2d2b4165bb6 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -223,7 +223,7 @@ func resourceGlobalClusterUpdate(d *schema.ResourceData, meta interface{}) error } if d.HasChange("engine_version") { - if err := globalClusterUpgradeEngineVersion(d, conn); err != nil { + if err := globalClusterUpgradeEngineVersion(d, meta); err != nil { return err } } @@ -530,7 +530,7 @@ func waitForGlobalClusterRemoval(conn *rds.RDS, dbClusterIdentifier string, time return nil } -func globalClusterUpgradeMajorEngineVersion(clusterId string, engineVersion string, conn *rds.RDS) error { +func globalClusterUpgradeMajorEngineVersion(conn *rds.RDS, clusterId string, engineVersion string) error { input := &rds.ModifyGlobalClusterInput{ GlobalClusterIdentifier: aws.String(clusterId), } @@ -557,7 +557,9 @@ func globalClusterUpgradeMajorEngineVersion(clusterId string, engineVersion stri return err } -func globalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, engineVersion string, conn *rds.RDS) error { +func globalClusterUpgradeMinorEngineVersion(meta interface{}, clusterMembers *schema.Set, engineVersion string) error { + conn := meta.(*conns.AWSClient).RDSConn + for _, clusterMemberRaw := range clusterMembers.List() { clusterMember := clusterMemberRaw.(map[string]interface{}) @@ -569,6 +571,10 @@ func globalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, engineVe } dbi := "" + useConn := conn + + // DBClusterIdentifier supposedly can be either ARN or ID, and both used to work, + // but as of now, only ID works if parsedARN.Resource != "" { parts := strings.Split(parsedARN.Resource, ":") @@ -580,6 +586,10 @@ func globalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, engineVe dbi = parts[1] } + if parsedARN.Region != meta.(*conns.AWSClient).Region { + useConn = rds.New(meta.(*conns.AWSClient).Session, aws.NewConfig().WithRegion(parsedARN.Region)) + } + modInput := &rds.ModifyDBClusterInput{ ApplyImmediately: aws.Bool(true), DBClusterIdentifier: aws.String(dbi), @@ -587,7 +597,7 @@ func globalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, engineVe } err = resource.Retry(clusterInitiateUpgradeTimeout, func() *resource.RetryError { - _, err := conn.ModifyDBCluster(modInput) + _, err := useConn.ModifyDBCluster(modInput) if err != nil { if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "IAM role ARN value is invalid or does not include the required permissions") { return resource.RetryableError(err) @@ -604,12 +614,14 @@ func globalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, engineVe } return nil }) + if tfresource.TimedOut(err) { - _, err := conn.ModifyDBCluster(modInput) + _, err := useConn.ModifyDBCluster(modInput) if err != nil { return err } } + if err != nil { return fmt.Errorf("failed to update engine_version on RDS Global Cluster member (%s): %s", clusterMemberArn, err) } @@ -618,11 +630,13 @@ func globalClusterUpgradeMinorEngineVersion(clusterMembers *schema.Set, engineVe return nil } -func globalClusterUpgradeEngineVersion(d *schema.ResourceData, conn *rds.RDS) error { +func globalClusterUpgradeEngineVersion(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).RDSConn + log.Printf("[DEBUG] Upgrading RDS Global Cluster (%s) engine version: %s", d.Id(), d.Get("engine_version")) - err := globalClusterUpgradeMajorEngineVersion(d.Id(), d.Get("engine_version").(string), conn) + err := globalClusterUpgradeMajorEngineVersion(conn, d.Id(), d.Get("engine_version").(string)) if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "ModifyGlobalCluster only supports Major Version Upgrades. To patch the members of your global cluster to a newer minor version you need to call ModifyDbCluster in each one of them.") { - err = globalClusterUpgradeMinorEngineVersion(d.Get("global_cluster_members").(*schema.Set), d.Get("engine_version").(string), conn) + err = globalClusterUpgradeMinorEngineVersion(meta, d.Get("global_cluster_members").(*schema.Set), d.Get("engine_version").(string)) if err != nil { return err } diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index 4ab1dd98861..2da19aa07e9 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -708,7 +708,7 @@ resource "aws_rds_cluster" "test2" { lifecycle { ignore_changes = [global_cluster_identifier] - } + } } resource "aws_rds_cluster_instance" "test2" { From ab96f11e7441c6263afb24bb3f48bc4841bdd661 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Fri, 11 Mar 2022 08:59:39 -0500 Subject: [PATCH 205/229] Remove bad comment --- internal/service/rds/global_cluster_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index 2da19aa07e9..d73d82f8883 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -624,8 +624,6 @@ resource "aws_rds_global_cluster" "test" { global_cluster_identifier = %[3]q } -// checkout the newly working global cluster stuff in cluster - resource "aws_rds_cluster" "test" { apply_immediately = true allow_major_version_upgrade = true From 1f4c4b4ae31b8608f8025dca9d8fbb32c0029013 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Sat, 12 Mar 2022 21:40:08 -0500 Subject: [PATCH 206/229] rds_global_cluster: Fix upgrade capability --- internal/service/rds/cluster.go | 5 +- internal/service/rds/global_cluster.go | 255 ++++++++++++++------ internal/service/rds/global_cluster_test.go | 222 ++++++++++++++--- internal/service/rds/wait.go | 2 +- 4 files changed, 368 insertions(+), 116 deletions(-) diff --git a/internal/service/rds/cluster.go b/internal/service/rds/cluster.go index 681a403b00b..b6c459a00ef 100644 --- a/internal/service/rds/cluster.go +++ b/internal/service/rds/cluster.go @@ -139,6 +139,7 @@ func ResourceCluster() *schema.Resource { "global_cluster_identifier": { Type: schema.TypeString, Optional: true, + Computed: true, }, "enable_global_write_forwarding": { @@ -953,8 +954,7 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { log.Printf("[INFO] RDS Cluster ID: %s", d.Id()) - log.Println( - "[INFO] Waiting for RDS Cluster to be available") + log.Println("[INFO] Waiting for RDS Cluster to be available") stateConf := &resource.StateChangeConf{ Pending: resourceClusterCreatePendingStates, @@ -1515,6 +1515,7 @@ func waitForClusterUpdate(conn *rds.RDS, id string, timeout time.Duration) error MinTimeout: 10 * time.Second, Delay: 30 * time.Second, // Wait 30 secs before starting } + _, err := stateConf.WaitForState() return err } diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index 2d2b4165bb6..ed8a62e9554 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -8,6 +8,7 @@ import ( "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/service/rds" "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -20,7 +21,7 @@ import ( const ( GlobalClusterRemovalTimeout = 30 * time.Minute globalClusterCreateTimeout = 30 * time.Minute - globalClusterUpdateTimeout = 30 * time.Minute + globalClusterUpdateTimeout = 5 * time.Minute ) func ResourceGlobalCluster() *schema.Resource { @@ -246,19 +247,6 @@ func resourceGlobalClusterUpdate(d *schema.ResourceData, meta interface{}) error return resourceGlobalClusterRead(d, meta) } -func globalClusterGetIDByARN(conn *rds.RDS, arn string) string { - result, err := conn.DescribeDBClusters(&rds.DescribeDBClustersInput{}) - if err != nil { - return "" - } - for _, cluster := range result.DBClusters { - if aws.StringValue(cluster.DBClusterArn) == arn { - return aws.StringValue(cluster.DBClusterIdentifier) - } - } - return "" -} - func resourceGlobalClusterDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).RDSConn @@ -444,6 +432,32 @@ func globalClusterRefreshFunc(conn *rds.RDS, globalClusterID string) resource.St } } +func globalClusterVersionRefreshFunc(conn *rds.RDS, globalClusterID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + globalCluster, err := DescribeGlobalCluster(conn, globalClusterID) + + if tfawserr.ErrCodeEquals(err, rds.ErrCodeGlobalClusterNotFoundFault) { + return nil, "deleted", nil + } + + if err != nil { + return nil, "", fmt.Errorf("error reading RDS Global Cluster (%s): %s", globalClusterID, err) + } + + if globalCluster == nil { + return nil, "deleted", nil + } + + status := aws.StringValue(globalCluster.Status) + + if status == rds.CustomEngineVersionStatusAvailable { + status = aws.StringValue(globalCluster.EngineVersion) + } + + return globalCluster, status, nil + } +} + func waitForGlobalClusterCreation(conn *rds.RDS, globalClusterID string, timeout time.Duration) error { stateConf := &resource.StateChangeConf{ Pending: []string{"creating"}, @@ -473,6 +487,21 @@ func waitForGlobalClusterUpdate(conn *rds.RDS, globalClusterID string, timeout t return err } +func waitForGlobalClusterVersionUpdate(conn *rds.RDS, globalClusterID, version string, timeout time.Duration) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{"modifying", "upgrading"}, + Target: []string{version}, + Refresh: globalClusterVersionRefreshFunc(conn, globalClusterID), + Timeout: timeout, + Delay: 30 * time.Second, + } + + log.Printf("[DEBUG] Waiting for RDS Global Cluster (%s) version sync", globalClusterID) + _, err := stateConf.WaitForState() + + return err +} + func WaitForGlobalClusterDeletion(conn *rds.RDS, globalClusterID string, timeout time.Duration) error { stateConf := &resource.StateChangeConf{ Pending: []string{ @@ -530,18 +559,24 @@ func waitForGlobalClusterRemoval(conn *rds.RDS, dbClusterIdentifier string, time return nil } -func globalClusterUpgradeMajorEngineVersion(conn *rds.RDS, clusterId string, engineVersion string) error { +func globalClusterUpgradeMajorEngineVersion(meta interface{}, clusterId string, engineVersion string) error { + conn := meta.(*conns.AWSClient).RDSConn + input := &rds.ModifyGlobalClusterInput{ GlobalClusterIdentifier: aws.String(clusterId), } + input.AllowMajorVersionUpgrade = aws.Bool(true) input.EngineVersion = aws.String(engineVersion) + err := resource.Retry(clusterInitiateUpgradeTimeout, func() *resource.RetryError { _, err := conn.ModifyGlobalCluster(input) + if err != nil { if tfawserr.ErrCodeEquals(err, rds.ErrCodeGlobalClusterNotFoundFault) { return resource.NonRetryableError(err) } + if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "ModifyGlobalCluster only supports Major Version Upgrades. To patch the members of your global cluster to a newer minor version you need to call ModifyDbCluster in each one of them.") { return resource.NonRetryableError(err) } @@ -551,107 +586,177 @@ func globalClusterUpgradeMajorEngineVersion(conn *rds.RDS, clusterId string, eng return nil }) + if tfresource.TimedOut(err) { _, err = conn.ModifyGlobalCluster(input) } + + if err != nil { + return fmt.Errorf("while upgrading major version of RDS Global Cluster (%s): %w", clusterId, err) + } + + globalCluster, err := DescribeGlobalCluster(conn, clusterId) + + if err != nil { + return fmt.Errorf("while upgrading major version of RDS Global Cluster (%s): %w", clusterId, err) + } + + for _, clusterMember := range globalCluster.GlobalClusterMembers { + arnID := aws.StringValue(clusterMember.DBClusterArn) + + if arnID == "" { + continue + } + + dbi, clusterRegion, err := ClusterIDRegionFromARN(arnID) + + if err != nil { + return fmt.Errorf("while upgrading RDS Global Cluster Cluster minor engine version: %w", err) + } + + if dbi == "" { + continue + } + + useConn := conn // clusters may not all be in the same region + + if clusterRegion != meta.(*conns.AWSClient).Region { + useConn = rds.New(meta.(*conns.AWSClient).Session, aws.NewConfig().WithRegion(clusterRegion)) + } + + if err := waitForClusterUpdate(useConn, dbi, clusterInitiateUpgradeTimeout); err != nil { + return fmt.Errorf("failed to update engine_version, waiting for RDS Global Cluster (%s) to update: %s", dbi, err) + } + } + return err } -func globalClusterUpgradeMinorEngineVersion(meta interface{}, clusterMembers *schema.Set, engineVersion string) error { +func ClusterIDRegionFromARN(arnID string) (string, string, error) { + parsedARN, err := arn.Parse(arnID) + + if err != nil { + return "", "", fmt.Errorf("could not parse ARN (%s): %w", arnID, err) + } + + dbi := "" + + if parsedARN.Resource != "" { + parts := strings.Split(parsedARN.Resource, ":") + + if len(parts) < 2 { + return "", "", fmt.Errorf("could not get DB Cluster ID from parsing ARN (%s): %w", arnID, err) + } + + if parsedARN.Service != endpoints.RdsServiceID || parts[0] != "cluster" { + return "", "", fmt.Errorf("wrong ARN (%s) for a DB Cluster", arnID) + } + + dbi = parts[1] + } + + return dbi, parsedARN.Region, nil +} + +func globalClusterUpgradeMinorEngineVersion(meta interface{}, clusterMembers *schema.Set, clusterID, engineVersion string) error { conn := meta.(*conns.AWSClient).RDSConn for _, clusterMemberRaw := range clusterMembers.List() { clusterMember := clusterMemberRaw.(map[string]interface{}) - if clusterMemberArn, ok := clusterMember["db_cluster_arn"]; ok && clusterMemberArn.(string) != "" { - parsedARN, err := arn.Parse(clusterMemberArn.(string)) - - if err != nil { - return fmt.Errorf("could not parse ARN while upgrading RDS Global Cluster minor engine version: %w", err) - } + // DBClusterIdentifier supposedly can be either ARN or ID, and both used to work, + // but as of now, only ID works + if clusterMemberArn, ok := clusterMember["db_cluster_arn"]; !ok || clusterMemberArn.(string) == "" { + continue + } - dbi := "" - useConn := conn + arnID := clusterMember["db_cluster_arn"].(string) - // DBClusterIdentifier supposedly can be either ARN or ID, and both used to work, - // but as of now, only ID works + dbi, clusterRegion, err := ClusterIDRegionFromARN(arnID) - if parsedARN.Resource != "" { - parts := strings.Split(parsedARN.Resource, ":") + if err != nil { + return fmt.Errorf("while upgrading RDS Global Cluster Cluster minor engine version: %w", err) + } - if len(parts) < 2 { - return fmt.Errorf("could not get DB Cluster ID from parsing ARN while upgrading RDS Global Cluster minor engine version: %w", err) - } + if dbi == "" { + continue + } - dbi = parts[1] - } + useConn := conn - if parsedARN.Region != meta.(*conns.AWSClient).Region { - useConn = rds.New(meta.(*conns.AWSClient).Session, aws.NewConfig().WithRegion(parsedARN.Region)) - } + if clusterRegion != meta.(*conns.AWSClient).Region { + useConn = rds.New(meta.(*conns.AWSClient).Session, aws.NewConfig().WithRegion(clusterRegion)) + } - modInput := &rds.ModifyDBClusterInput{ - ApplyImmediately: aws.Bool(true), - DBClusterIdentifier: aws.String(dbi), - EngineVersion: aws.String(engineVersion), - } + modInput := &rds.ModifyDBClusterInput{ + ApplyImmediately: aws.Bool(true), + DBClusterIdentifier: aws.String(dbi), + EngineVersion: aws.String(engineVersion), + } - err = resource.Retry(clusterInitiateUpgradeTimeout, func() *resource.RetryError { - _, err := useConn.ModifyDBCluster(modInput) - if err != nil { - if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "IAM role ARN value is invalid or does not include the required permissions") { - return resource.RetryableError(err) - } + err = resource.Retry(clusterInitiateUpgradeTimeout, func() *resource.RetryError { + _, err := useConn.ModifyDBCluster(modInput) - if tfawserr.ErrMessageContains(err, rds.ErrCodeInvalidDBClusterStateFault, "Cannot modify engine version without a primary instance in DB cluster") { - return resource.NonRetryableError(err) - } + if err != nil { + if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "IAM role ARN value is invalid or does not include the required permissions") { + return resource.RetryableError(err) + } - if tfawserr.ErrCodeEquals(err, rds.ErrCodeInvalidDBClusterStateFault) { - return resource.RetryableError(err) - } + if tfawserr.ErrMessageContains(err, rds.ErrCodeInvalidDBClusterStateFault, "Cannot modify engine version without a primary instance in DB cluster") { return resource.NonRetryableError(err) } - return nil - }) - if tfresource.TimedOut(err) { - _, err := useConn.ModifyDBCluster(modInput) - if err != nil { - return err + if tfawserr.ErrCodeEquals(err, rds.ErrCodeInvalidDBClusterStateFault) { + return resource.RetryableError(err) } + + return resource.NonRetryableError(err) } + return nil + }) + + if tfresource.TimedOut(err) { + _, err := useConn.ModifyDBCluster(modInput) if err != nil { - return fmt.Errorf("failed to update engine_version on RDS Global Cluster member (%s): %s", clusterMemberArn, err) + return err } } + + if err != nil { + return fmt.Errorf("failed to update engine_version on RDS Global Cluster Cluster (%s): %s", dbi, err) + } + + if err := waitForClusterUpdate(useConn, dbi, clusterInitiateUpgradeTimeout); err != nil { + return fmt.Errorf("failed to update engine_version, waiting for RDS Global Cluster Cluster (%s) to update: %s", dbi, err) + } + } + + if err := waitForGlobalClusterVersionUpdate(conn, clusterID, engineVersion, clusterInitiateUpgradeTimeout); err != nil { + return fmt.Errorf("failed to update engine_version, waiting for RDS Global Cluster (%s) to update: %s", clusterID, err) } + return nil } func globalClusterUpgradeEngineVersion(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*conns.AWSClient).RDSConn - log.Printf("[DEBUG] Upgrading RDS Global Cluster (%s) engine version: %s", d.Id(), d.Get("engine_version")) - err := globalClusterUpgradeMajorEngineVersion(conn, d.Id(), d.Get("engine_version").(string)) + + err := globalClusterUpgradeMajorEngineVersion(meta, d.Id(), d.Get("engine_version").(string)) + if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "ModifyGlobalCluster only supports Major Version Upgrades. To patch the members of your global cluster to a newer minor version you need to call ModifyDbCluster in each one of them.") { - err = globalClusterUpgradeMinorEngineVersion(meta, d.Get("global_cluster_members").(*schema.Set), d.Get("engine_version").(string)) + err = globalClusterUpgradeMinorEngineVersion(meta, d.Get("global_cluster_members").(*schema.Set), d.Id(), d.Get("engine_version").(string)) + if err != nil { - return err + return fmt.Errorf("while upgrading minor version of RDS Global Cluster (%s): %w", d.Id(), err) } - } else if err != nil { - return err + + return nil } - globalCluster, err := DescribeGlobalCluster(conn, d.Id()) + if err != nil { - return err - } - for _, clusterMember := range globalCluster.GlobalClusterMembers { - err := waitForClusterUpdate(conn, globalClusterGetIDByARN(conn, aws.StringValue(clusterMember.DBClusterArn)), d.Timeout(schema.TimeoutUpdate)) - if err != nil { - return err - } + return fmt.Errorf("while upgrading major version of RDS Global Cluster (%s): %w", d.Id(), err) } + return nil } diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index d73d82f8883..71674e82c96 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -18,6 +18,77 @@ import ( tfrds "github.com/hashicorp/terraform-provider-aws/internal/service/rds" ) +func TestClusterIDRegionFromARN(t *testing.T) { + testCases := []struct { + TestName string + Input string + ExpectedID string + ExpectedRegion string + ExpectedErr bool + }{ + { + TestName: "empty", + Input: "", + ExpectedID: "", + ExpectedRegion: "", + ExpectedErr: true, + }, + { + TestName: "normal ARN", + Input: "arn:aws:rds:us-west-2:012345678901:cluster:tf-acc-test-1467354933239945971", + ExpectedID: "tf-acc-test-1467354933239945971", + ExpectedRegion: "us-west-2", + ExpectedErr: false, + }, + { + TestName: "another good ARN", + Input: "arn:aws:rds:us-east-1:012345678901:cluster:tf-acc-test-1467354933239945971", + ExpectedID: "tf-acc-test-1467354933239945971", + ExpectedRegion: "us-east-1", + ExpectedErr: false, + }, + { + TestName: "no account", + Input: "arn:aws:rds:us-east-2::cluster:tf-acc-test-1467354933239945971", + ExpectedID: "tf-acc-test-1467354933239945971", + ExpectedRegion: "us-east-2", + ExpectedErr: false, + }, + { + TestName: "wrong service", + Input: "arn:aws:connect:us-west-2:012345678901:instance/1032bdc4-d72c-5490-a9fa-3c9b4dba67bb", + ExpectedID: "", + ExpectedRegion: "", + ExpectedErr: true, + }, + { + TestName: "wrong resource", + Input: "arn:aws:rds:us-east-2::notacluster:tf-acc-test-1467354933239945971", + ExpectedID: "", + ExpectedRegion: "", + ExpectedErr: true, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.TestName, func(t *testing.T) { + gotID, gotRegion, gotErr := tfrds.ClusterIDRegionFromARN(testCase.Input) + + if gotErr != nil && !testCase.ExpectedErr { + t.Errorf("got no error, expected one: %s", testCase.Input) + } + + if gotID != testCase.ExpectedID { + t.Errorf("got %s, expected %s", gotID, testCase.ExpectedID) + } + + if gotRegion != testCase.ExpectedRegion { + t.Errorf("got %s, expected %s", gotRegion, testCase.ExpectedRegion) + } + }) + } +} + func TestAccRDSGlobalCluster_basic(t *testing.T) { var globalCluster1 rds.GlobalCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -272,7 +343,9 @@ func TestAccRDSGlobalCluster_EngineVersion_updateMajor(t *testing.T) { func TestAccRDSGlobalCluster_EngineVersion_updateMinorMultiRegion(t *testing.T) { var providers []*schema.Provider var globalCluster1, globalCluster2 rds.GlobalCluster - rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rNameGlobal := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) // don't need to be unique but makes debugging easier + rNamePrimary := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rNameSecondary := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_global_cluster.test" resource.ParallelTest(t, resource.TestCase{ @@ -282,17 +355,49 @@ func TestAccRDSGlobalCluster_EngineVersion_updateMinorMultiRegion(t *testing.T) CheckDestroy: testAccCheckGlobalClusterDestroy, Steps: []resource.TestStep{ { - Config: testAccGlobalClusterEngineVersionUpgradeMultiRegionConfig(rName, "aurora", "5.6.mysql_aurora.1.22.2"), + Config: testAccGlobalClusterEngineVersionUpgradeMultiRegionConfig(rNameGlobal, rNamePrimary, rNameSecondary, "aurora-mysql", "5.7.mysql_aurora.2.07.5"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster1), ), }, { - Config: testAccGlobalClusterEngineVersionUpgradeMultiRegionConfig(rName, "aurora", "5.6.mysql_aurora.1.23.2"), + Config: testAccGlobalClusterEngineVersionUpgradeMultiRegionConfig(rNameGlobal, rNamePrimary, rNameSecondary, "aurora-mysql", "5.7.mysql_aurora.2.07.7"), Check: resource.ComposeTestCheckFunc( testAccCheckGlobalClusterExists(resourceName, &globalCluster2), testAccCheckGlobalClusterNotRecreated(&globalCluster1, &globalCluster2), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.6.mysql_aurora.1.23.2"), + resource.TestCheckResourceAttr(resourceName, "engine_version", "5.7.mysql_aurora.2.07.7"), + ), + }, + }, + }) +} + +func TestAccRDSGlobalCluster_EngineVersion_updateMajorMultiRegion(t *testing.T) { + var providers []*schema.Provider + var globalCluster1, globalCluster2 rds.GlobalCluster + rNameGlobal := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) // don't need to be unique but makes debugging easier + rNamePrimary := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rNameSecondary := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_rds_global_cluster.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckGlobalCluster(t) }, + ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), + ProviderFactories: acctest.FactoriesAlternate(&providers), + CheckDestroy: testAccCheckGlobalClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccGlobalClusterEngineVersionUpgradeMultiRegionConfig(rNameGlobal, rNamePrimary, rNameSecondary, "aurora", "5.6.mysql_aurora.1.23.4"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGlobalClusterExists(resourceName, &globalCluster1), + ), + }, + { + Config: testAccGlobalClusterEngineVersionUpgradeMultiRegionConfig(rNameGlobal, rNamePrimary, rNameSecondary, "aurora-mysql", "5.7.mysql_aurora.2.10.2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckGlobalClusterExists(resourceName, &globalCluster2), + testAccCheckGlobalClusterNotRecreated(&globalCluster1, &globalCluster2), + resource.TestCheckResourceAttr(resourceName, "engine_version", "5.7.mysql_aurora.2.10.2"), ), }, }, @@ -656,70 +761,111 @@ resource "aws_rds_cluster_instance" "test" { `, engine, engineVersion, rName) } -func testAccGlobalClusterEngineVersionUpgradeMultiRegionConfig(rName, engine, engineVersion string) string { +func testAccGlobalClusterEngineVersionUpgradeMultiRegionConfig(rNameGlobal, rNamePrimary, rNameSecondary, engine, engineVersion string) string { return acctest.ConfigCompose( - acctest.ConfigAlternateRegionProvider(), + acctest.ConfigMultipleRegionProvider(2), fmt.Sprintf(` +data "aws_region" "current" {} + +data "aws_availability_zones" "alternate" { + provider = "awsalternate" + state = "available" + + filter { + name = "opt-in-status" + values = ["opt-in-not-required"] + } +} + resource "aws_rds_global_cluster" "test" { - engine = %[1]q - engine_version = %[2]q - global_cluster_identifier = %[3]q + global_cluster_identifier = %[1]q + engine = %[2]q + engine_version = %[3]q } -resource "aws_rds_cluster" "test" { +resource "aws_rds_cluster" "primary" { allow_major_version_upgrade = true apply_immediately = true - cluster_identifier = %[3]q + cluster_identifier = %[4]q database_name = "totoro" engine = aws_rds_global_cluster.test.engine engine_version = aws_rds_global_cluster.test.engine_version - global_cluster_identifier = aws_rds_global_cluster.test.global_cluster_identifier - master_password = "mustbeeightcharacters" - master_username = "test" + global_cluster_identifier = aws_rds_global_cluster.test.id + master_password = "satsukimae" + master_username = "maesatsuki" skip_final_snapshot = true lifecycle { - ignore_changes = [global_cluster_identifier] + ignore_changes = [engine_version] } } -resource "aws_rds_cluster_instance" "test" { +resource "aws_rds_cluster_instance" "primary" { apply_immediately = true - cluster_identifier = aws_rds_cluster.test.id - engine = aws_rds_global_cluster.test.engine - engine_version = aws_rds_global_cluster.test.engine_version - identifier = %[3]q - instance_class = "db.r3.large" + cluster_identifier = aws_rds_cluster.primary.id + engine = aws_rds_cluster.primary.engine + engine_version = aws_rds_cluster.primary.engine_version + identifier = %[4]q + instance_class = "db.r4.large" } -resource "aws_rds_cluster" "test2" { - provider = "awsalternate" +resource "aws_vpc" "alternate" { + provider = "awsalternate" + cidr_block = "10.0.0.0/16" + + tags = { + Name = %[5]q + } +} + +resource "aws_subnet" "alternate" { + provider = "awsalternate" + count = 3 + vpc_id = aws_vpc.alternate.id + availability_zone = data.aws_availability_zones.alternate.names[count.index] + cidr_block = "10.0.${count.index}.0/24" + tags = { + Name = %[5]q + } +} + +resource "aws_db_subnet_group" "alternate" { + provider = "awsalternate" + name = %[5]q + subnet_ids = aws_subnet.alternate[*].id +} + +resource "aws_rds_cluster" "secondary" { + provider = "awsalternate" allow_major_version_upgrade = true apply_immediately = true - cluster_identifier = "%[3]s-2" - engine = %[1]q - engine_version = %[2]q - global_cluster_identifier = aws_rds_global_cluster.test.global_cluster_identifier - replication_source_identifier = aws_rds_cluster.test.arn + cluster_identifier = %[5]q + engine = aws_rds_global_cluster.test.engine + engine_version = aws_rds_global_cluster.test.engine_version + global_cluster_identifier = aws_rds_global_cluster.test.id skip_final_snapshot = true lifecycle { - ignore_changes = [global_cluster_identifier] + ignore_changes = [ + replication_source_identifier, + engine_version, + ] } -} -resource "aws_rds_cluster_instance" "test2" { - provider = "awsalternate" + depends_on = [aws_rds_cluster_instance.primary] +} +resource "aws_rds_cluster_instance" "secondary" { + provider = "awsalternate" apply_immediately = true - cluster_identifier = aws_rds_cluster.test2.id - engine = %[1]q - engine_version = %[2]q - identifier = "%[3]s-2" - instance_class = "db.r3.large" + cluster_identifier = aws_rds_cluster.secondary.id + engine = aws_rds_cluster.secondary.engine + engine_version = aws_rds_cluster.secondary.engine_version + identifier = %[5]q + instance_class = "db.r4.large" } -`, engine, engineVersion, rName)) +`, rNameGlobal, engine, engineVersion, rNamePrimary, rNameSecondary)) } func testAccGlobalClusterSourceClusterIdentifierConfig(rName string) string { diff --git a/internal/service/rds/wait.go b/internal/service/rds/wait.go index 096fe77f506..2450b406f6a 100644 --- a/internal/service/rds/wait.go +++ b/internal/service/rds/wait.go @@ -8,7 +8,7 @@ import ( ) const ( - clusterInitiateUpgradeTimeout = 5 * time.Minute + clusterInitiateUpgradeTimeout = 30 * time.Minute dbClusterRoleAssociationCreatedTimeout = 5 * time.Minute dbClusterRoleAssociationDeletedTimeout = 5 * time.Minute From dc7e520af8fae2156a51fe0bbcc7410de1f0e69a Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Sat, 12 Mar 2022 21:42:24 -0500 Subject: [PATCH 207/229] Update changelog --- .changelog/23560.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/23560.txt b/.changelog/23560.txt index 681fa41670f..167ba9437ae 100644 --- a/.changelog/23560.txt +++ b/.changelog/23560.txt @@ -7,7 +7,7 @@ resource/aws_db_instance: Fix issues where configured update timeout was not res ``` ```release-note:bug -resource/aws_rds_global_cluster: Fix in-place DB Cluster minor version upgrade error: "Invalid database cluster identifier" +resource/aws_rds_global_cluster: Fix ability to perform DB Cluster minor version upgrades of clusters in distinct regions, including error: "Invalid database cluster identifier" ``` ```release-note:enhancement From 35947129fbf421f3428652fe75197b3a18cd55fa Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Sat, 12 Mar 2022 22:12:58 -0500 Subject: [PATCH 208/229] Fix waiter error --- internal/service/rds/global_cluster.go | 6 +-- .../docs/r/rds_global_cluster.html.markdown | 43 +++++++++++++++++-- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index ed8a62e9554..2df05f605fd 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -432,7 +432,7 @@ func globalClusterRefreshFunc(conn *rds.RDS, globalClusterID string) resource.St } } -func globalClusterVersionRefreshFunc(conn *rds.RDS, globalClusterID string) resource.StateRefreshFunc { +func globalClusterVersionRefreshFunc(conn *rds.RDS, globalClusterID, engineVersion string) resource.StateRefreshFunc { return func() (interface{}, string, error) { globalCluster, err := DescribeGlobalCluster(conn, globalClusterID) @@ -450,7 +450,7 @@ func globalClusterVersionRefreshFunc(conn *rds.RDS, globalClusterID string) reso status := aws.StringValue(globalCluster.Status) - if status == rds.CustomEngineVersionStatusAvailable { + if status == rds.CustomEngineVersionStatusAvailable && aws.StringValue(globalCluster.EngineVersion) == engineVersion { status = aws.StringValue(globalCluster.EngineVersion) } @@ -491,7 +491,7 @@ func waitForGlobalClusterVersionUpdate(conn *rds.RDS, globalClusterID, version s stateConf := &resource.StateChangeConf{ Pending: []string{"modifying", "upgrading"}, Target: []string{version}, - Refresh: globalClusterVersionRefreshFunc(conn, globalClusterID), + Refresh: globalClusterVersionRefreshFunc(conn, globalClusterID, version), Timeout: timeout, Delay: 30 * time.Second, } diff --git a/website/docs/r/rds_global_cluster.html.markdown b/website/docs/r/rds_global_cluster.html.markdown index ad39c887419..7ce3e88701b 100644 --- a/website/docs/r/rds_global_cluster.html.markdown +++ b/website/docs/r/rds_global_cluster.html.markdown @@ -162,16 +162,53 @@ resource "aws_rds_global_cluster" "example" { } ``` +### Upgrading Engine Versions + +When you upgrade the version of an `aws_rds_global_cluster`, Terraform will attempt to in-place upgrade the engine versions of all associated clusters. Since the `aws_rds_cluster` resource is being updated through the `aws_rds_global_cluster`, you are likely to get an error (`Provider produced inconsistent final plan`). To avoid this, use the `lifecycle` `ignore_changes` meta argument as shown below. + +```terraform +resource "aws_rds_global_cluster" "example" { + global_cluster_identifier = "kyivkharkiv" + engine = "aurora-mysql" + engine_version = "5.7.mysql_aurora.2.07.5" +} + +resource "aws_rds_cluster" "primary" { + allow_major_version_upgrade = true + apply_immediately = true + cluster_identifier = "odessadnipro" + database_name = "totoro" + engine = aws_rds_global_cluster.example.engine + engine_version = aws_rds_global_cluster.example.engine_version + global_cluster_identifier = aws_rds_global_cluster.example.id + master_password = "satsukimae" + master_username = "maesatsuki" + skip_final_snapshot = true + + lifecycle { + ignore_changes = [engine_version] + } +} + +resource "aws_rds_cluster_instance" "primary" { + apply_immediately = true + cluster_identifier = aws_rds_cluster.primary.id + engine = aws_rds_cluster.primary.engine + engine_version = aws_rds_cluster.primary.engine_version + identifier = "donetsklviv" + instance_class = "db.r4.large" +} +``` + ## Argument Reference The following arguments are supported: -* `global_cluster_identifier` - (Required, Forces new resources) The global cluster identifier. +* `global_cluster_identifier` - (Required, Forces new resources) Global cluster identifier. * `database_name` - (Optional, Forces new resources) Name for an automatically created database on cluster creation. * `deletion_protection` - (Optional) If the Global Cluster should have deletion protection enabled. The database can't be deleted when this value is set to `true`. The default is `false`. * `engine` - (Optional, Forces new resources) Name of the database engine to be used for this DB cluster. Terraform will only perform drift detection if a configuration value is provided. Valid values: `aurora`, `aurora-mysql`, `aurora-postgresql`. Defaults to `aurora`. Conflicts with `source_db_cluster_identifier`. -* `engine_version` - (Optional) Engine version of the Aurora global database. Upgrading the engine version will result in all cluster members being immediately updated. - * **NOTE:** When the engine is set to `aurora-mysql`, an engine version compatible with global database is required. The earliest available version is `5.7.mysql_aurora.2.06.0`. +* `engine_version` - (Optional) Engine version of the Aurora global database. The `engine`, `engine_version`, and `instance_class` (on the `aws_rds_cluster_instance`) must together support global databases. See [Using Amazon Aurora global databases](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-global-database.html) for more information. By upgrading the engine version, Terraform will upgrade cluster members. **NOTE:** To avoid an `inconsistent final plan` error while upgrading, use the `lifecycle` `ignore_changes` for `engine_version` meta argument on the associated `aws_rds_cluster` resource as shown above in [Upgrading Engine Versions](#upgrading-engine-versions) example. * `force_destroy` - (Optional) Enable to remove DB Cluster members from Global Cluster on destroy. Required with `source_db_cluster_identifier`. * `source_db_cluster_identifier` - (Optional) Amazon Resource Name (ARN) to use as the primary DB Cluster of the Global Cluster on creation. Terraform cannot perform drift detection of this value. * `storage_encrypted` - (Optional, Forces new resources) Specifies whether the DB cluster is encrypted. The default is `false` unless `source_db_cluster_identifier` is specified and encrypted. Terraform will only perform drift detection if a configuration value is provided. From 23299c8a33f769cf7c7d289dd2d57d81daba0a35 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Sat, 12 Mar 2022 22:19:05 -0500 Subject: [PATCH 209/229] Update changelog --- .changelog/23560.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/23560.txt b/.changelog/23560.txt index 167ba9437ae..b6c3749f681 100644 --- a/.changelog/23560.txt +++ b/.changelog/23560.txt @@ -7,7 +7,7 @@ resource/aws_db_instance: Fix issues where configured update timeout was not res ``` ```release-note:bug -resource/aws_rds_global_cluster: Fix ability to perform DB Cluster minor version upgrades of clusters in distinct regions, including error: "Invalid database cluster identifier" +resource/aws_rds_global_cluster: Fix ability to perform cluster version upgrades, including of clusters in distinct regions, such as error: "Invalid database cluster identifier" ``` ```release-note:enhancement From 9ca642bb9ba62274bc84b8b06b6e023c27369a0b Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Sat, 12 Mar 2022 22:20:22 -0500 Subject: [PATCH 210/229] Update changelog --- .changelog/23560.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/23560.txt b/.changelog/23560.txt index b6c3749f681..5787a897152 100644 --- a/.changelog/23560.txt +++ b/.changelog/23560.txt @@ -7,7 +7,7 @@ resource/aws_db_instance: Fix issues where configured update timeout was not res ``` ```release-note:bug -resource/aws_rds_global_cluster: Fix ability to perform cluster version upgrades, including of clusters in distinct regions, such as error: "Invalid database cluster identifier" +resource/aws_rds_global_cluster: Fix ability to perform cluster version upgrades, including of clusters in distinct regions, such as previously got error: "Invalid database cluster identifier" ``` ```release-note:enhancement From 910f0e36ee6cbf78a98db07d9af6d7ce2f988a36 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Sat, 12 Mar 2022 22:23:22 -0500 Subject: [PATCH 211/229] rds_cluster: Restore to original schema --- internal/service/rds/cluster.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/service/rds/cluster.go b/internal/service/rds/cluster.go index b6c459a00ef..32084974fe2 100644 --- a/internal/service/rds/cluster.go +++ b/internal/service/rds/cluster.go @@ -139,7 +139,6 @@ func ResourceCluster() *schema.Resource { "global_cluster_identifier": { Type: schema.TypeString, Optional: true, - Computed: true, }, "enable_global_write_forwarding": { From 9963e7b7dab820f6b05c090bc778a32fc027ce0f Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Sat, 12 Mar 2022 22:25:07 -0500 Subject: [PATCH 212/229] rds_global_cluster: Fix timeout --- internal/service/rds/global_cluster.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index 2df05f605fd..934b4fb00c0 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -21,7 +21,7 @@ import ( const ( GlobalClusterRemovalTimeout = 30 * time.Minute globalClusterCreateTimeout = 30 * time.Minute - globalClusterUpdateTimeout = 5 * time.Minute + globalClusterUpdateTimeout = 30 * time.Minute ) func ResourceGlobalCluster() *schema.Resource { From d888392caf9717b112b7987c23db09a43ce56050 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 14 Mar 2022 12:24:15 -0400 Subject: [PATCH 213/229] rds_global_cluster: Finally --- internal/service/rds/global_cluster.go | 38 ++++++++++++++----- .../docs/r/rds_global_cluster.html.markdown | 2 +- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index 934b4fb00c0..f019af4e942 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -21,7 +21,7 @@ import ( const ( GlobalClusterRemovalTimeout = 30 * time.Minute globalClusterCreateTimeout = 30 * time.Minute - globalClusterUpdateTimeout = 30 * time.Minute + globalClusterUpdateTimeout = 60 * time.Minute ) func ResourceGlobalCluster() *schema.Resource { @@ -489,7 +489,7 @@ func waitForGlobalClusterUpdate(conn *rds.RDS, globalClusterID string, timeout t func waitForGlobalClusterVersionUpdate(conn *rds.RDS, globalClusterID, version string, timeout time.Duration) error { stateConf := &resource.StateChangeConf{ - Pending: []string{"modifying", "upgrading"}, + Pending: []string{"modifying", "upgrading", "available"}, Target: []string{version}, Refresh: globalClusterVersionRefreshFunc(conn, globalClusterID, version), Timeout: timeout, @@ -559,11 +559,11 @@ func waitForGlobalClusterRemoval(conn *rds.RDS, dbClusterIdentifier string, time return nil } -func globalClusterUpgradeMajorEngineVersion(meta interface{}, clusterId string, engineVersion string) error { +func globalClusterUpgradeMajorEngineVersion(meta interface{}, clusterID string, engineVersion string) error { conn := meta.(*conns.AWSClient).RDSConn input := &rds.ModifyGlobalClusterInput{ - GlobalClusterIdentifier: aws.String(clusterId), + GlobalClusterIdentifier: aws.String(clusterID), } input.AllowMajorVersionUpgrade = aws.Bool(true) @@ -592,13 +592,13 @@ func globalClusterUpgradeMajorEngineVersion(meta interface{}, clusterId string, } if err != nil { - return fmt.Errorf("while upgrading major version of RDS Global Cluster (%s): %w", clusterId, err) + return fmt.Errorf("while upgrading major version of RDS Global Cluster (%s): %w", clusterID, err) } - globalCluster, err := DescribeGlobalCluster(conn, clusterId) + globalCluster, err := DescribeGlobalCluster(conn, clusterID) if err != nil { - return fmt.Errorf("while upgrading major version of RDS Global Cluster (%s): %w", clusterId, err) + return fmt.Errorf("while upgrading major version of RDS Global Cluster (%s): %w", clusterID, err) } for _, clusterMember := range globalCluster.GlobalClusterMembers { @@ -661,6 +661,8 @@ func ClusterIDRegionFromARN(arnID string) (string, string, error) { func globalClusterUpgradeMinorEngineVersion(meta interface{}, clusterMembers *schema.Set, clusterID, engineVersion string) error { conn := meta.(*conns.AWSClient).RDSConn + log.Printf("[INFO] Performing RDS Global Cluster (%s) minor version (%s) upgrade", clusterID, engineVersion) + for _, clusterMemberRaw := range clusterMembers.List() { clusterMember := clusterMemberRaw.(map[string]interface{}) @@ -694,6 +696,8 @@ func globalClusterUpgradeMinorEngineVersion(meta interface{}, clusterMembers *sc EngineVersion: aws.String(engineVersion), } + log.Printf("[INFO] Performing RDS Global Cluster (%s) Cluster (%s) minor version (%s) upgrade", clusterID, dbi, engineVersion) + err = resource.Retry(clusterInitiateUpgradeTimeout, func() *resource.RetryError { _, err := useConn.ModifyDBCluster(modInput) @@ -727,13 +731,29 @@ func globalClusterUpgradeMinorEngineVersion(meta interface{}, clusterMembers *sc return fmt.Errorf("failed to update engine_version on RDS Global Cluster Cluster (%s): %s", dbi, err) } + log.Printf("[INFO] Waiting for RDS Global Cluster (%s) Cluster (%s) minor version (%s) upgrade", clusterID, dbi, engineVersion) if err := waitForClusterUpdate(useConn, dbi, clusterInitiateUpgradeTimeout); err != nil { return fmt.Errorf("failed to update engine_version, waiting for RDS Global Cluster Cluster (%s) to update: %s", dbi, err) } } - if err := waitForGlobalClusterVersionUpdate(conn, clusterID, engineVersion, clusterInitiateUpgradeTimeout); err != nil { - return fmt.Errorf("failed to update engine_version, waiting for RDS Global Cluster (%s) to update: %s", clusterID, err) + globalCluster, err := DescribeGlobalCluster(conn, clusterID) + + if tfawserr.ErrCodeEquals(err, rds.ErrCodeGlobalClusterNotFoundFault) { + return fmt.Errorf("after upgrading engine_version, could not find RDS Global Cluster (%s): %s", clusterID, err) + } + + if err != nil { + return fmt.Errorf("after minor engine_version upgrade to RDS Global Cluster (%s): %s", clusterID, err) + } + + if globalCluster == nil { + return fmt.Errorf("after minor engine_version upgrade to RDS Global Cluster (%s): empty response", clusterID) + } + + if aws.StringValue(globalCluster.EngineVersion) != engineVersion { + log.Printf("[DEBUG] RDS Global Cluster (%s) upgrade did not take effect, trying again", clusterID) + return globalClusterUpgradeMinorEngineVersion(meta, clusterMembers, clusterID, engineVersion) } return nil diff --git a/website/docs/r/rds_global_cluster.html.markdown b/website/docs/r/rds_global_cluster.html.markdown index 7ce3e88701b..ccb51211999 100644 --- a/website/docs/r/rds_global_cluster.html.markdown +++ b/website/docs/r/rds_global_cluster.html.markdown @@ -164,7 +164,7 @@ resource "aws_rds_global_cluster" "example" { ### Upgrading Engine Versions -When you upgrade the version of an `aws_rds_global_cluster`, Terraform will attempt to in-place upgrade the engine versions of all associated clusters. Since the `aws_rds_cluster` resource is being updated through the `aws_rds_global_cluster`, you are likely to get an error (`Provider produced inconsistent final plan`). To avoid this, use the `lifecycle` `ignore_changes` meta argument as shown below. +When you upgrade the version of an `aws_rds_global_cluster`, Terraform will attempt to in-place upgrade the engine versions of all associated clusters. Since the `aws_rds_cluster` resource is being updated through the `aws_rds_global_cluster`, you are likely to get an error (`Provider produced inconsistent final plan`). To avoid this, use the `lifecycle` `ignore_changes` meta argument as shown below on the `aws_rds_cluster`. ```terraform resource "aws_rds_global_cluster" "example" { From 5e15ff399a91141b19a1d8798a6456c65ca0662b Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 12:36:44 -0400 Subject: [PATCH 214/229] Add CHANGELOG entry. --- .changelog/23517.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/23517.txt diff --git a/.changelog/23517.txt b/.changelog/23517.txt new file mode 100644 index 00000000000..9ab4adb7e08 --- /dev/null +++ b/.changelog/23517.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_amplify_app: Allow `repository` to be updated in-place +``` \ No newline at end of file From 86eaf8feba6b8040c22f43e7d096cf33288c3fc9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 12:39:02 -0400 Subject: [PATCH 215/229] Increase sleep time between Amplify tests in an attempt to reduce errors like 'Rate exceeded while calling CreateApp, please slow down or try again later.'. --- internal/service/amplify/amplify_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/amplify/amplify_test.go b/internal/service/amplify/amplify_test.go index e23728f1686..75d4fd2f985 100644 --- a/internal/service/amplify/amplify_test.go +++ b/internal/service/amplify/amplify_test.go @@ -55,7 +55,7 @@ func TestAccAmplify_serial(t *testing.T) { t.Run(name, func(t *testing.T) { tc(t) // Explicitly sleep between tests. - time.Sleep(5 * time.Second) + time.Sleep(15 * time.Second) }) } }) From 86acf3385db8e7bd40274589306bb8102cdef9cc Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 14 Mar 2022 12:49:41 -0400 Subject: [PATCH 216/229] Linted windows --- internal/service/rds/global_cluster_test.go | 26 ++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index 71674e82c96..c87bfd42b79 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -35,35 +35,35 @@ func TestClusterIDRegionFromARN(t *testing.T) { }, { TestName: "normal ARN", - Input: "arn:aws:rds:us-west-2:012345678901:cluster:tf-acc-test-1467354933239945971", + Input: "arn:aws:rds:us-west-2:012345678901:cluster:tf-acc-test-1467354933239945971", // lintignore:AWSAT003,AWSAT005 ExpectedID: "tf-acc-test-1467354933239945971", ExpectedRegion: "us-west-2", ExpectedErr: false, }, { TestName: "another good ARN", - Input: "arn:aws:rds:us-east-1:012345678901:cluster:tf-acc-test-1467354933239945971", + Input: "arn:aws:rds:us-east-1:012345678901:cluster:tf-acc-test-1467354933239945971", // lintignore:AWSAT003,AWSAT005 ExpectedID: "tf-acc-test-1467354933239945971", ExpectedRegion: "us-east-1", ExpectedErr: false, }, { TestName: "no account", - Input: "arn:aws:rds:us-east-2::cluster:tf-acc-test-1467354933239945971", + Input: "arn:aws:rds:us-east-2::cluster:tf-acc-test-1467354933239945971", // lintignore:AWSAT003,AWSAT005 ExpectedID: "tf-acc-test-1467354933239945971", ExpectedRegion: "us-east-2", ExpectedErr: false, }, { TestName: "wrong service", - Input: "arn:aws:connect:us-west-2:012345678901:instance/1032bdc4-d72c-5490-a9fa-3c9b4dba67bb", + Input: "arn:aws:connect:us-west-2:012345678901:instance/1032bdc4-d72c-5490-a9fa-3c9b4dba67bb", // lintignore:AWSAT003,AWSAT005 ExpectedID: "", ExpectedRegion: "", ExpectedErr: true, }, { TestName: "wrong resource", - Input: "arn:aws:rds:us-east-2::notacluster:tf-acc-test-1467354933239945971", + Input: "arn:aws:rds:us-east-2::notacluster:tf-acc-test-1467354933239945971", // lintignore:AWSAT003,AWSAT005 ExpectedID: "", ExpectedRegion: "", ExpectedErr: true, @@ -837,14 +837,14 @@ resource "aws_db_subnet_group" "alternate" { } resource "aws_rds_cluster" "secondary" { - provider = "awsalternate" - allow_major_version_upgrade = true - apply_immediately = true - cluster_identifier = %[5]q - engine = aws_rds_global_cluster.test.engine - engine_version = aws_rds_global_cluster.test.engine_version - global_cluster_identifier = aws_rds_global_cluster.test.id - skip_final_snapshot = true + provider = "awsalternate" + allow_major_version_upgrade = true + apply_immediately = true + cluster_identifier = %[5]q + engine = aws_rds_global_cluster.test.engine + engine_version = aws_rds_global_cluster.test.engine_version + global_cluster_identifier = aws_rds_global_cluster.test.id + skip_final_snapshot = true lifecycle { ignore_changes = [ From 491af321070deefbb4303bc86f32217a19c583a9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 12:52:59 -0400 Subject: [PATCH 217/229] Change 'ParallelTest' to 'Test' so that the test are actually serialized. --- internal/service/amplify/app_test.go | 24 +++++++++---------- .../amplify/backend_environment_test.go | 6 ++--- internal/service/amplify/branch_test.go | 12 +++++----- .../amplify/domain_association_test.go | 6 ++--- internal/service/amplify/webhook_test.go | 6 ++--- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/internal/service/amplify/app_test.go b/internal/service/amplify/app_test.go index ced02e1051f..8777fe97d85 100644 --- a/internal/service/amplify/app_test.go +++ b/internal/service/amplify/app_test.go @@ -23,7 +23,7 @@ func testAccApp_basic(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_app.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -70,7 +70,7 @@ func testAccApp_disappears(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_app.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -93,7 +93,7 @@ func testAccApp_Tags(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_app.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -140,7 +140,7 @@ func testAccApp_AutoBranchCreationConfig(t *testing.T) { credentials := base64.StdEncoding.EncodeToString([]byte("username1:password1")) - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -236,7 +236,7 @@ func testAccApp_BasicAuthCredentials(t *testing.T) { credentials1 := base64.StdEncoding.EncodeToString([]byte("username1:password1")) credentials2 := base64.StdEncoding.EncodeToString([]byte("username2:password2")) - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -281,7 +281,7 @@ func testAccApp_BuildSpec(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_app.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -323,7 +323,7 @@ func testAccApp_CustomRules(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_app.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -373,7 +373,7 @@ func testAccApp_Description(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_app.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -416,7 +416,7 @@ func testAccApp_EnvironmentVariables(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_app.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -462,7 +462,7 @@ func testAccApp_IAMServiceRole(t *testing.T) { iamRole1ResourceName := "aws_iam_role.test1" iamRole2ResourceName := "aws_iam_role.test2" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -505,7 +505,7 @@ func testAccApp_Name(t *testing.T) { rName2 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_app.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -551,7 +551,7 @@ func testAccApp_Repository(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_app.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, diff --git a/internal/service/amplify/backend_environment_test.go b/internal/service/amplify/backend_environment_test.go index ba8549348e2..2c1d0caac38 100644 --- a/internal/service/amplify/backend_environment_test.go +++ b/internal/service/amplify/backend_environment_test.go @@ -22,7 +22,7 @@ func testAccBackendEnvironment_basic(t *testing.T) { environmentName := sdkacctest.RandStringFromCharSet(10, sdkacctest.CharSetAlpha) - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -54,7 +54,7 @@ func testAccBackendEnvironment_disappears(t *testing.T) { environmentName := sdkacctest.RandStringFromCharSet(10, sdkacctest.CharSetAlpha) - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -79,7 +79,7 @@ func testAccBackendEnvironment_DeploymentArtifacts_StackName(t *testing.T) { environmentName := sdkacctest.RandStringFromCharSet(10, sdkacctest.CharSetAlpha) - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, diff --git a/internal/service/amplify/branch_test.go b/internal/service/amplify/branch_test.go index b87afc9ce73..fcf1486877d 100644 --- a/internal/service/amplify/branch_test.go +++ b/internal/service/amplify/branch_test.go @@ -21,7 +21,7 @@ func testAccBranch_basic(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_branch.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -68,7 +68,7 @@ func testAccBranch_disappears(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_branch.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -91,7 +91,7 @@ func testAccBranch_Tags(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_branch.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -139,7 +139,7 @@ func testAccBranch_BasicAuthCredentials(t *testing.T) { credentials1 := base64.StdEncoding.EncodeToString([]byte("username1:password1")) credentials2 := base64.StdEncoding.EncodeToString([]byte("username2:password2")) - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -184,7 +184,7 @@ func testAccBranch_EnvironmentVariables(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_branch.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -231,7 +231,7 @@ func testAccBranch_OptionalArguments(t *testing.T) { backendEnvironment1ResourceName := "aws_amplify_backend_environment.test1" backendEnvironment2ResourceName := "aws_amplify_backend_environment.test2" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, diff --git a/internal/service/amplify/domain_association_test.go b/internal/service/amplify/domain_association_test.go index 7cdd1bc327d..daa4f74f8ef 100644 --- a/internal/service/amplify/domain_association_test.go +++ b/internal/service/amplify/domain_association_test.go @@ -27,7 +27,7 @@ func testAccDomainAssociation_basic(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_domain_association.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -68,7 +68,7 @@ func testAccDomainAssociation_disappears(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_domain_association.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -97,7 +97,7 @@ func testAccDomainAssociation_update(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_domain_association.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, diff --git a/internal/service/amplify/webhook_test.go b/internal/service/amplify/webhook_test.go index 6e157fd5e8e..ee721049f29 100644 --- a/internal/service/amplify/webhook_test.go +++ b/internal/service/amplify/webhook_test.go @@ -20,7 +20,7 @@ func testAccWebhook_basic(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_webhook.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -50,7 +50,7 @@ func testAccWebhook_disappears(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_webhook.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, @@ -73,7 +73,7 @@ func testAccWebhook_update(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_amplify_webhook.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, amplify.EndpointsID), Providers: acctest.Providers, From 791f7f89805123d2e4b444681a709ccd85d0ffb5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 14 Mar 2022 12:53:09 -0400 Subject: [PATCH 218/229] Revert "Increase sleep time between Amplify tests in an attempt to reduce errors like 'Rate exceeded while calling CreateApp, please slow down or try again later.'." This reverts commit 86eaf8feba6b8040c22f43e7d096cf33288c3fc9. --- internal/service/amplify/amplify_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/amplify/amplify_test.go b/internal/service/amplify/amplify_test.go index 75d4fd2f985..e23728f1686 100644 --- a/internal/service/amplify/amplify_test.go +++ b/internal/service/amplify/amplify_test.go @@ -55,7 +55,7 @@ func TestAccAmplify_serial(t *testing.T) { t.Run(name, func(t *testing.T) { tc(t) // Explicitly sleep between tests. - time.Sleep(15 * time.Second) + time.Sleep(5 * time.Second) }) } }) From b88585b927c84647ba15cd5ab609764e4ab077cd Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 14 Mar 2022 13:02:05 -0400 Subject: [PATCH 219/229] Final lint --- internal/service/rds/global_cluster_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index c87bfd42b79..44f1fc99963 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -37,21 +37,21 @@ func TestClusterIDRegionFromARN(t *testing.T) { TestName: "normal ARN", Input: "arn:aws:rds:us-west-2:012345678901:cluster:tf-acc-test-1467354933239945971", // lintignore:AWSAT003,AWSAT005 ExpectedID: "tf-acc-test-1467354933239945971", - ExpectedRegion: "us-west-2", + ExpectedRegion: "us-west-2", // lintignore:AWSAT003 ExpectedErr: false, }, { TestName: "another good ARN", Input: "arn:aws:rds:us-east-1:012345678901:cluster:tf-acc-test-1467354933239945971", // lintignore:AWSAT003,AWSAT005 ExpectedID: "tf-acc-test-1467354933239945971", - ExpectedRegion: "us-east-1", + ExpectedRegion: "us-east-1", // lintignore:AWSAT003 ExpectedErr: false, }, { TestName: "no account", Input: "arn:aws:rds:us-east-2::cluster:tf-acc-test-1467354933239945971", // lintignore:AWSAT003,AWSAT005 ExpectedID: "tf-acc-test-1467354933239945971", - ExpectedRegion: "us-east-2", + ExpectedRegion: "us-east-2", // lintignore:AWSAT003 ExpectedErr: false, }, { From 7424144b66b8b4e99641942f40a705d5a5b89192 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 14 Mar 2022 13:44:56 -0400 Subject: [PATCH 220/229] Remove unused --- internal/service/rds/global_cluster.go | 41 -------------------------- 1 file changed, 41 deletions(-) diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index f019af4e942..fd45ed01482 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -432,32 +432,6 @@ func globalClusterRefreshFunc(conn *rds.RDS, globalClusterID string) resource.St } } -func globalClusterVersionRefreshFunc(conn *rds.RDS, globalClusterID, engineVersion string) resource.StateRefreshFunc { - return func() (interface{}, string, error) { - globalCluster, err := DescribeGlobalCluster(conn, globalClusterID) - - if tfawserr.ErrCodeEquals(err, rds.ErrCodeGlobalClusterNotFoundFault) { - return nil, "deleted", nil - } - - if err != nil { - return nil, "", fmt.Errorf("error reading RDS Global Cluster (%s): %s", globalClusterID, err) - } - - if globalCluster == nil { - return nil, "deleted", nil - } - - status := aws.StringValue(globalCluster.Status) - - if status == rds.CustomEngineVersionStatusAvailable && aws.StringValue(globalCluster.EngineVersion) == engineVersion { - status = aws.StringValue(globalCluster.EngineVersion) - } - - return globalCluster, status, nil - } -} - func waitForGlobalClusterCreation(conn *rds.RDS, globalClusterID string, timeout time.Duration) error { stateConf := &resource.StateChangeConf{ Pending: []string{"creating"}, @@ -487,21 +461,6 @@ func waitForGlobalClusterUpdate(conn *rds.RDS, globalClusterID string, timeout t return err } -func waitForGlobalClusterVersionUpdate(conn *rds.RDS, globalClusterID, version string, timeout time.Duration) error { - stateConf := &resource.StateChangeConf{ - Pending: []string{"modifying", "upgrading", "available"}, - Target: []string{version}, - Refresh: globalClusterVersionRefreshFunc(conn, globalClusterID, version), - Timeout: timeout, - Delay: 30 * time.Second, - } - - log.Printf("[DEBUG] Waiting for RDS Global Cluster (%s) version sync", globalClusterID) - _, err := stateConf.WaitForState() - - return err -} - func WaitForGlobalClusterDeletion(conn *rds.RDS, globalClusterID string, timeout time.Duration) error { stateConf := &resource.StateChangeConf{ Pending: []string{ From 974fa731d058f902859c8722e5989400245e4134 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 14 Mar 2022 14:16:02 -0400 Subject: [PATCH 221/229] rds: Add long-test guards --- internal/service/rds/cluster_endpoint_test.go | 8 + internal/service/rds/cluster_instance_test.go | 96 ++++ internal/service/rds/cluster_test.go | 124 ++++++ internal/service/rds/global_cluster_test.go | 16 + .../service/rds/instance_data_source_test.go | 8 + .../rds/instance_role_association_test.go | 8 + internal/service/rds/instance_test.go | 416 ++++++++++++++++++ internal/service/rds/option_group_test.go | 4 + .../orderable_instance_data_source_test.go | 40 ++ .../service/rds/proxy_data_source_test.go | 4 + .../rds/proxy_default_target_group_test.go | 32 ++ internal/service/rds/proxy_endpoint_test.go | 24 + internal/service/rds/proxy_target_test.go | 12 + internal/service/rds/proxy_test.go | 48 ++ .../service/rds/snapshot_data_source_test.go | 4 + internal/service/rds/snapshot_test.go | 12 + 16 files changed, 856 insertions(+) diff --git a/internal/service/rds/cluster_endpoint_test.go b/internal/service/rds/cluster_endpoint_test.go index c463959741a..754bad93244 100644 --- a/internal/service/rds/cluster_endpoint_test.go +++ b/internal/service/rds/cluster_endpoint_test.go @@ -18,6 +18,10 @@ import ( ) func TestAccRDSClusterEndpoint_basic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + rInt := sdkacctest.RandInt() var customReaderEndpoint rds.DBClusterEndpoint var customEndpoint rds.DBClusterEndpoint @@ -61,6 +65,10 @@ func TestAccRDSClusterEndpoint_basic(t *testing.T) { } func TestAccRDSClusterEndpoint_tags(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + rInt := sdkacctest.RandInt() var customReaderEndpoint rds.DBClusterEndpoint resourceName := "aws_rds_cluster_endpoint.reader" diff --git a/internal/service/rds/cluster_instance_test.go b/internal/service/rds/cluster_instance_test.go index d688a4a6f6d..a2a18595f16 100644 --- a/internal/service/rds/cluster_instance_test.go +++ b/internal/service/rds/cluster_instance_test.go @@ -19,6 +19,10 @@ import ( ) func TestAccRDSClusterInstance_basic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance resourceName := "aws_rds_cluster_instance.cluster_instances" @@ -66,6 +70,10 @@ func TestAccRDSClusterInstance_basic(t *testing.T) { } func TestAccRDSClusterInstance_isAlreadyBeingDeleted(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance resourceName := "aws_rds_cluster_instance.cluster_instances" rInt := sdkacctest.RandInt() @@ -103,6 +111,10 @@ func TestAccRDSClusterInstance_isAlreadyBeingDeleted(t *testing.T) { } func TestAccRDSClusterInstance_az(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance resourceName := "aws_rds_cluster_instance.cluster_instances" availabilityZonesDataSourceName := "data.aws_availability_zones.available" @@ -135,6 +147,10 @@ func TestAccRDSClusterInstance_az(t *testing.T) { } func TestAccRDSClusterInstance_namePrefix(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance rInt := sdkacctest.RandInt() resourceName := "aws_rds_cluster_instance.test" @@ -168,6 +184,10 @@ func TestAccRDSClusterInstance_namePrefix(t *testing.T) { } func TestAccRDSClusterInstance_generatedName(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance resourceName := "aws_rds_cluster_instance.test" @@ -199,6 +219,10 @@ func TestAccRDSClusterInstance_generatedName(t *testing.T) { } func TestAccRDSClusterInstance_kmsKey(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance kmsKeyResourceName := "aws_kms_key.foo" resourceName := "aws_rds_cluster_instance.cluster_instances" @@ -231,6 +255,10 @@ func TestAccRDSClusterInstance_kmsKey(t *testing.T) { // https://github.com/hashicorp/terraform/issues/5350 func TestAccRDSClusterInstance_disappears(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance resourceName := "aws_rds_cluster_instance.cluster_instances" @@ -253,6 +281,10 @@ func TestAccRDSClusterInstance_disappears(t *testing.T) { } func TestAccRDSClusterInstance_publiclyAccessible(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_cluster_instance.test" @@ -291,6 +323,10 @@ func TestAccRDSClusterInstance_publiclyAccessible(t *testing.T) { } func TestAccRDSClusterInstance_copyTagsToSnapshot(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rNameSuffix := sdkacctest.RandInt() resourceName := "aws_rds_cluster_instance.cluster_instances" @@ -329,6 +365,10 @@ func TestAccRDSClusterInstance_copyTagsToSnapshot(t *testing.T) { } func TestAccRDSClusterInstance_monitoringInterval(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance resourceName := "aws_rds_cluster_instance.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -381,6 +421,10 @@ func TestAccRDSClusterInstance_monitoringInterval(t *testing.T) { } func TestAccRDSClusterInstance_MonitoringRoleARN_enabledToDisabled(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance iamRoleResourceName := "aws_iam_role.test" resourceName := "aws_rds_cluster_instance.test" @@ -420,6 +464,10 @@ func TestAccRDSClusterInstance_MonitoringRoleARN_enabledToDisabled(t *testing.T) } func TestAccRDSClusterInstance_MonitoringRoleARN_enabledToRemoved(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance iamRoleResourceName := "aws_iam_role.test" resourceName := "aws_rds_cluster_instance.test" @@ -458,6 +506,10 @@ func TestAccRDSClusterInstance_MonitoringRoleARN_enabledToRemoved(t *testing.T) } func TestAccRDSClusterInstance_MonitoringRoleARN_removedToEnabled(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance iamRoleResourceName := "aws_iam_role.test" resourceName := "aws_rds_cluster_instance.test" @@ -496,6 +548,10 @@ func TestAccRDSClusterInstance_MonitoringRoleARN_removedToEnabled(t *testing.T) } func TestAccRDSClusterInstance_PerformanceInsightsEnabled_auroraMySQL1(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance resourceName := "aws_rds_cluster_instance.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -528,6 +584,10 @@ func TestAccRDSClusterInstance_PerformanceInsightsEnabled_auroraMySQL1(t *testin } func TestAccRDSClusterInstance_PerformanceInsightsEnabled_auroraMySQL2(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance resourceName := "aws_rds_cluster_instance.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -561,6 +621,10 @@ func TestAccRDSClusterInstance_PerformanceInsightsEnabled_auroraMySQL2(t *testin } func TestAccRDSClusterInstance_PerformanceInsightsEnabled_auroraPostgresql(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance resourceName := "aws_rds_cluster_instance.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -593,6 +657,10 @@ func TestAccRDSClusterInstance_PerformanceInsightsEnabled_auroraPostgresql(t *te } func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyID_auroraMySQL1(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance kmsKeyResourceName := "aws_kms_key.test" resourceName := "aws_rds_cluster_instance.test" @@ -627,6 +695,10 @@ func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyID_auroraMySQL1(t *testi } func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyIDAuroraMySQL1_defaultKeyToCustomKey(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance resourceName := "aws_rds_cluster_instance.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -663,6 +735,10 @@ func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyIDAuroraMySQL1_defaultKe } func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyID_auroraMySQL2(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance kmsKeyResourceName := "aws_kms_key.test" resourceName := "aws_rds_cluster_instance.test" @@ -698,6 +774,10 @@ func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyID_auroraMySQL2(t *testi } func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyIDAuroraMySQL2_defaultKeyToCustomKey(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance resourceName := "aws_rds_cluster_instance.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -735,6 +815,10 @@ func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyIDAuroraMySQL2_defaultKe } func TestAccRDSClusterInstance_performanceInsightsRetentionPeriod(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance resourceName := "aws_rds_cluster_instance.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -775,6 +859,10 @@ func TestAccRDSClusterInstance_performanceInsightsRetentionPeriod(t *testing.T) } func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyID_auroraPostgresql(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance kmsKeyResourceName := "aws_kms_key.test" resourceName := "aws_rds_cluster_instance.test" @@ -809,6 +897,10 @@ func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyID_auroraPostgresql(t *t } func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyIDAuroraPostgresql_defaultKeyToCustomKey(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance resourceName := "aws_rds_cluster_instance.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -845,6 +937,10 @@ func TestAccRDSClusterInstance_PerformanceInsightsKMSKeyIDAuroraPostgresql_defau } func TestAccRDSClusterInstance_caCertificateIdentifier(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_cluster_instance.test" diff --git a/internal/service/rds/cluster_test.go b/internal/service/rds/cluster_test.go index d0abe29c25e..5324b6bcd2f 100644 --- a/internal/service/rds/cluster_test.go +++ b/internal/service/rds/cluster_test.go @@ -84,6 +84,10 @@ func TestAccRDSCluster_basic(t *testing.T) { } func TestAccRDSCluster_allowMajorVersionUpgrade(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster1, dbCluster2 rds.DBCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_cluster.test" @@ -137,6 +141,10 @@ func TestAccRDSCluster_allowMajorVersionUpgrade(t *testing.T) { } func TestAccRDSCluster_allowMajorVersionUpgradeWithCustomParametersApplyImm(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster1, dbCluster2 rds.DBCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_cluster.test" @@ -176,6 +184,10 @@ func TestAccRDSCluster_allowMajorVersionUpgradeWithCustomParametersApplyImm(t *t } func TestAccRDSCluster_allowMajorVersionUpgradeWithCustomParameters(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster1, dbCluster2 rds.DBCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_cluster.test" @@ -229,6 +241,10 @@ func TestAccRDSCluster_allowMajorVersionUpgradeWithCustomParameters(t *testing.T } func TestAccRDSCluster_onlyMajorVersion(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster1 rds.DBCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_cluster.test" @@ -364,6 +380,10 @@ func TestAccRDSCluster_dbSubnetGroupName(t *testing.T) { } func TestAccRDSCluster_s3Restore(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBCluster resourceName := "aws_rds_cluster.test" bucket := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -388,6 +408,10 @@ func TestAccRDSCluster_s3Restore(t *testing.T) { } func TestAccRDSCluster_pointInTimeRestore(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBCluster var c rds.DBCluster @@ -414,6 +438,10 @@ func TestAccRDSCluster_pointInTimeRestore(t *testing.T) { } func TestAccRDSCluster_PointInTimeRestore_enabledCloudWatchLogsExports(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBCluster var c rds.DBCluster @@ -725,6 +753,10 @@ func TestAccRDSCluster_copyTagsToSnapshot(t *testing.T) { } func TestAccRDSCluster_ReplicationSourceIdentifier_kmsKeyID(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var primaryCluster rds.DBCluster var replicaCluster rds.DBCluster resourceName := "aws_rds_cluster.test" @@ -846,6 +878,10 @@ func TestAccRDSCluster_deletionProtection(t *testing.T) { } func TestAccRDSCluster_engineMode(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster1, dbCluster2 rds.DBCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -948,6 +984,10 @@ func TestAccRDSCluster_EngineMode_parallelQuery(t *testing.T) { } func TestAccRDSCluster_engineVersion(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster rds.DBCluster rInt := sdkacctest.RandInt() resourceName := "aws_rds_cluster.test" @@ -976,6 +1016,10 @@ func TestAccRDSCluster_engineVersion(t *testing.T) { } func TestAccRDSCluster_engineVersionWithPrimaryInstance(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster rds.DBCluster rInt := sdkacctest.RandInt() resourceName := "aws_rds_cluster.test" @@ -1145,6 +1189,10 @@ func TestAccRDSCluster_GlobalClusterIdentifierEngineMode_provisioned(t *testing. // Reference: https://github.com/hashicorp/terraform-provider-aws/issues/13126 func TestAccRDSCluster_GlobalClusterIdentifier_primarySecondaryClusters(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var providers []*schema.Provider var primaryDbCluster, secondaryDbCluster rds.DBCluster @@ -1178,6 +1226,10 @@ func TestAccRDSCluster_GlobalClusterIdentifier_primarySecondaryClusters(t *testi // Reference: https://github.com/hashicorp/terraform-provider-aws/issues/13715 func TestAccRDSCluster_GlobalClusterIdentifier_replicationSourceIdentifier(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var providers []*schema.Provider var primaryDbCluster, secondaryDbCluster rds.DBCluster @@ -1208,6 +1260,10 @@ func TestAccRDSCluster_GlobalClusterIdentifier_replicationSourceIdentifier(t *te // Reference: https://github.com/hashicorp/terraform-provider-aws/issues/14457 func TestAccRDSCluster_GlobalClusterIdentifier_secondaryClustersWriteForwarding(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var providers []*schema.Provider var primaryDbCluster, secondaryDbCluster rds.DBCluster @@ -1270,6 +1326,10 @@ func TestAccRDSCluster_port(t *testing.T) { } func TestAccRDSCluster_scaling(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster rds.DBCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1339,6 +1399,10 @@ func TestAccRDSCluster_Scaling_defaultMinCapacity(t *testing.T) { } func TestAccRDSCluster_snapshotIdentifier(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster, sourceDbCluster rds.DBCluster var dbClusterSnapshot rds.DBClusterSnapshot @@ -1366,6 +1430,10 @@ func TestAccRDSCluster_snapshotIdentifier(t *testing.T) { } func TestAccRDSCluster_SnapshotIdentifier_deletionProtection(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster, sourceDbCluster rds.DBCluster var dbClusterSnapshot rds.DBClusterSnapshot @@ -1404,6 +1472,10 @@ func TestAccRDSCluster_SnapshotIdentifier_deletionProtection(t *testing.T) { } func TestAccRDSCluster_SnapshotIdentifierEngineMode_parallelQuery(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster, sourceDbCluster rds.DBCluster var dbClusterSnapshot rds.DBClusterSnapshot @@ -1432,6 +1504,10 @@ func TestAccRDSCluster_SnapshotIdentifierEngineMode_parallelQuery(t *testing.T) } func TestAccRDSCluster_SnapshotIdentifierEngineMode_provisioned(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster, sourceDbCluster rds.DBCluster var dbClusterSnapshot rds.DBClusterSnapshot @@ -1493,6 +1569,10 @@ func TestAccRDSCluster_SnapshotIdentifierEngineMode_serverless(t *testing.T) { // Reference: https://github.com/hashicorp/terraform-provider-aws/issues/6157 func TestAccRDSCluster_SnapshotIdentifierEngineVersion_different(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster, sourceDbCluster rds.DBCluster var dbClusterSnapshot rds.DBClusterSnapshot @@ -1523,6 +1603,10 @@ func TestAccRDSCluster_SnapshotIdentifierEngineVersion_different(t *testing.T) { // Reference: https://github.com/hashicorp/terraform-provider-aws/issues/6157 func TestAccRDSCluster_SnapshotIdentifierEngineVersion_equal(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster, sourceDbCluster rds.DBCluster var dbClusterSnapshot rds.DBClusterSnapshot @@ -1552,6 +1636,10 @@ func TestAccRDSCluster_SnapshotIdentifierEngineVersion_equal(t *testing.T) { } func TestAccRDSCluster_SnapshotIdentifier_kmsKeyID(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster, sourceDbCluster rds.DBCluster var dbClusterSnapshot rds.DBClusterSnapshot @@ -1581,6 +1669,10 @@ func TestAccRDSCluster_SnapshotIdentifier_kmsKeyID(t *testing.T) { } func TestAccRDSCluster_SnapshotIdentifier_masterPassword(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster, sourceDbCluster rds.DBCluster var dbClusterSnapshot rds.DBClusterSnapshot @@ -1609,6 +1701,10 @@ func TestAccRDSCluster_SnapshotIdentifier_masterPassword(t *testing.T) { } func TestAccRDSCluster_SnapshotIdentifier_masterUsername(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster, sourceDbCluster rds.DBCluster var dbClusterSnapshot rds.DBClusterSnapshot @@ -1639,6 +1735,10 @@ func TestAccRDSCluster_SnapshotIdentifier_masterUsername(t *testing.T) { } func TestAccRDSCluster_SnapshotIdentifier_preferredBackupWindow(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster, sourceDbCluster rds.DBCluster var dbClusterSnapshot rds.DBClusterSnapshot @@ -1667,6 +1767,10 @@ func TestAccRDSCluster_SnapshotIdentifier_preferredBackupWindow(t *testing.T) { } func TestAccRDSCluster_SnapshotIdentifier_preferredMaintenanceWindow(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster, sourceDbCluster rds.DBCluster var dbClusterSnapshot rds.DBClusterSnapshot @@ -1695,6 +1799,10 @@ func TestAccRDSCluster_SnapshotIdentifier_preferredMaintenanceWindow(t *testing. } func TestAccRDSCluster_SnapshotIdentifier_tags(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster, sourceDbCluster rds.DBCluster var dbClusterSnapshot rds.DBClusterSnapshot @@ -1724,6 +1832,10 @@ func TestAccRDSCluster_SnapshotIdentifier_tags(t *testing.T) { } func TestAccRDSCluster_SnapshotIdentifier_vpcSecurityGroupIDs(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster, sourceDbCluster rds.DBCluster var dbClusterSnapshot rds.DBClusterSnapshot @@ -1755,6 +1867,10 @@ func TestAccRDSCluster_SnapshotIdentifier_vpcSecurityGroupIDs(t *testing.T) { // vpc_security_group_ids is set (which triggered the resource update function), // and tags is set which was missing its ARN used for tagging func TestAccRDSCluster_SnapshotIdentifierVPCSecurityGroupIDs_tags(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster, sourceDbCluster rds.DBCluster var dbClusterSnapshot rds.DBClusterSnapshot @@ -1784,6 +1900,10 @@ func TestAccRDSCluster_SnapshotIdentifierVPCSecurityGroupIDs_tags(t *testing.T) } func TestAccRDSCluster_SnapshotIdentifier_encryptedRestore(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster, sourceDbCluster rds.DBCluster var dbClusterSnapshot rds.DBClusterSnapshot @@ -1814,6 +1934,10 @@ func TestAccRDSCluster_SnapshotIdentifier_encryptedRestore(t *testing.T) { } func TestAccRDSCluster_enableHTTPEndpoint(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbCluster rds.DBCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) diff --git a/internal/service/rds/global_cluster_test.go b/internal/service/rds/global_cluster_test.go index 44f1fc99963..dc2c4d15892 100644 --- a/internal/service/rds/global_cluster_test.go +++ b/internal/service/rds/global_cluster_test.go @@ -271,6 +271,10 @@ func TestAccRDSGlobalCluster_EngineVersion_aurora(t *testing.T) { } func TestAccRDSGlobalCluster_EngineVersion_updateMinor(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var globalCluster1, globalCluster2 rds.GlobalCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_global_cluster.test" @@ -307,6 +311,10 @@ func TestAccRDSGlobalCluster_EngineVersion_updateMinor(t *testing.T) { } func TestAccRDSGlobalCluster_EngineVersion_updateMajor(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var globalCluster1, globalCluster2 rds.GlobalCluster rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_rds_global_cluster.test" @@ -341,6 +349,10 @@ func TestAccRDSGlobalCluster_EngineVersion_updateMajor(t *testing.T) { } func TestAccRDSGlobalCluster_EngineVersion_updateMinorMultiRegion(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var providers []*schema.Provider var globalCluster1, globalCluster2 rds.GlobalCluster rNameGlobal := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) // don't need to be unique but makes debugging easier @@ -373,6 +385,10 @@ func TestAccRDSGlobalCluster_EngineVersion_updateMinorMultiRegion(t *testing.T) } func TestAccRDSGlobalCluster_EngineVersion_updateMajorMultiRegion(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var providers []*schema.Provider var globalCluster1, globalCluster2 rds.GlobalCluster rNameGlobal := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) // don't need to be unique but makes debugging easier diff --git a/internal/service/rds/instance_data_source_test.go b/internal/service/rds/instance_data_source_test.go index bbedf381724..254aac723e1 100644 --- a/internal/service/rds/instance_data_source_test.go +++ b/internal/service/rds/instance_data_source_test.go @@ -11,6 +11,10 @@ import ( ) func TestAccRDSInstanceDataSource_basic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) dataSourceName := "data.aws_db_instance.test" @@ -46,6 +50,10 @@ func TestAccRDSInstanceDataSource_basic(t *testing.T) { } func TestAccRDSInstanceDataSource_ec2Classic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) dataSourceName := "data.aws_db_instance.test" diff --git a/internal/service/rds/instance_role_association_test.go b/internal/service/rds/instance_role_association_test.go index 6fd567d89cd..bab6d99f05d 100644 --- a/internal/service/rds/instance_role_association_test.go +++ b/internal/service/rds/instance_role_association_test.go @@ -16,6 +16,10 @@ import ( ) func TestAccRDSInstanceRoleAssociation_basic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstanceRole1 rds.DBInstanceRole rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) dbInstanceResourceName := "aws_db_instance.test" @@ -47,6 +51,10 @@ func TestAccRDSInstanceRoleAssociation_basic(t *testing.T) { } func TestAccRDSInstanceRoleAssociation_disappears(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance1 rds.DBInstance var dbInstanceRole1 rds.DBInstanceRole rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) diff --git a/internal/service/rds/instance_test.go b/internal/service/rds/instance_test.go index ca3b4baaf4b..53c4aee5c0e 100644 --- a/internal/service/rds/instance_test.go +++ b/internal/service/rds/instance_test.go @@ -23,6 +23,10 @@ import ( ) func TestAccRDSInstance_basic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance1 rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -92,6 +96,10 @@ func TestAccRDSInstance_basic(t *testing.T) { } func TestAccRDSInstance_NameDeprecated_basic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance1 rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -162,6 +170,10 @@ func TestAccRDSInstance_NameDeprecated_basic(t *testing.T) { } func TestAccRDSInstance_onlyMajorVersion(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance1 rds.DBInstance resourceName := "aws_db_instance.test" engine := "mysql" @@ -195,6 +207,10 @@ func TestAccRDSInstance_onlyMajorVersion(t *testing.T) { } func TestAccRDSInstance_namePrefix(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance const identifierPrefix = "tf-acc-test-prefix-" @@ -227,6 +243,10 @@ func TestAccRDSInstance_namePrefix(t *testing.T) { } func TestAccRDSInstance_nameGenerated(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance const resourceName = "aws_db_instance.test" @@ -258,6 +278,10 @@ func TestAccRDSInstance_nameGenerated(t *testing.T) { } func TestAccRDSInstance_kmsKey(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance kmsKeyResourceName := "aws_kms_key.foo" resourceName := "aws_db_instance.bar" @@ -294,6 +318,10 @@ func TestAccRDSInstance_kmsKey(t *testing.T) { } func TestAccRDSInstance_subnetGroup(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_instance.test" @@ -323,6 +351,10 @@ func TestAccRDSInstance_subnetGroup(t *testing.T) { } func TestAccRDSInstance_optionGroup(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -347,6 +379,10 @@ func TestAccRDSInstance_optionGroup(t *testing.T) { } func TestAccRDSInstance_iamAuth(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -370,6 +406,10 @@ func TestAccRDSInstance_iamAuth(t *testing.T) { } func TestAccRDSInstance_allowMajorVersionUpgrade(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance1 rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -412,6 +452,10 @@ func TestAccRDSInstance_allowMajorVersionUpgrade(t *testing.T) { } func TestAccRDSInstance_dbSubnetGroupName(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance var dbSubnetGroup rds.DBSubnetGroup @@ -469,6 +513,10 @@ func TestAccRDSInstance_DBSubnetGroupName_ramShared(t *testing.T) { } func TestAccRDSInstance_DBSubnetGroupName_vpcSecurityGroupIDs(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance var dbSubnetGroup rds.DBSubnetGroup @@ -495,6 +543,10 @@ func TestAccRDSInstance_DBSubnetGroupName_vpcSecurityGroupIDs(t *testing.T) { } func TestAccRDSInstance_deletionProtection(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -537,6 +589,10 @@ func TestAccRDSInstance_deletionProtection(t *testing.T) { } func TestAccRDSInstance_finalSnapshotIdentifier(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var snap rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -559,6 +615,10 @@ func TestAccRDSInstance_finalSnapshotIdentifier(t *testing.T) { } func TestAccRDSInstance_FinalSnapshotIdentifier_skipFinalSnapshot(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var snap rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -579,6 +639,10 @@ func TestAccRDSInstance_FinalSnapshotIdentifier_skipFinalSnapshot(t *testing.T) } func TestAccRDSInstance_isAlreadyBeingDeleted(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -617,6 +681,10 @@ func TestAccRDSInstance_isAlreadyBeingDeleted(t *testing.T) { } func TestAccRDSInstance_maxAllocatedStorage(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -661,6 +729,10 @@ func TestAccRDSInstance_maxAllocatedStorage(t *testing.T) { } func TestAccRDSInstance_password(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -700,6 +772,10 @@ func TestAccRDSInstance_password(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_basic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -737,6 +813,10 @@ func TestAccRDSInstance_ReplicateSourceDB_basic(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_namePrefix(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance sourceName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -770,6 +850,10 @@ func TestAccRDSInstance_ReplicateSourceDB_namePrefix(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_nameGenerated(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance sourceName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -802,6 +886,10 @@ func TestAccRDSInstance_ReplicateSourceDB_nameGenerated(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_addLater(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -833,6 +921,10 @@ func TestAccRDSInstance_ReplicateSourceDB_addLater(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_allocatedStorage(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -859,6 +951,10 @@ func TestAccRDSInstance_ReplicateSourceDB_allocatedStorage(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_iops(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -885,6 +981,10 @@ func TestAccRDSInstance_ReplicateSourceDB_iops(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_allocatedStorageAndIops(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -912,6 +1012,10 @@ func TestAccRDSInstance_ReplicateSourceDB_allocatedStorageAndIops(t *testing.T) } func TestAccRDSInstance_ReplicateSourceDB_allowMajorVersionUpgrade(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -938,6 +1042,10 @@ func TestAccRDSInstance_ReplicateSourceDB_allowMajorVersionUpgrade(t *testing.T) } func TestAccRDSInstance_ReplicateSourceDB_autoMinorVersionUpgrade(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -964,6 +1072,10 @@ func TestAccRDSInstance_ReplicateSourceDB_autoMinorVersionUpgrade(t *testing.T) } func TestAccRDSInstance_ReplicateSourceDB_availabilityZone(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -989,6 +1101,10 @@ func TestAccRDSInstance_ReplicateSourceDB_availabilityZone(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_backupRetentionPeriod(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1015,6 +1131,10 @@ func TestAccRDSInstance_ReplicateSourceDB_backupRetentionPeriod(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_backupWindow(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1041,6 +1161,10 @@ func TestAccRDSInstance_ReplicateSourceDB_backupWindow(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_dbSubnetGroupName(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance var dbSubnetGroup rds.DBSubnetGroup var providers []*schema.Provider @@ -1071,6 +1195,10 @@ func TestAccRDSInstance_ReplicateSourceDB_dbSubnetGroupName(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDBDBSubnetGroupName_ramShared(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance var dbSubnetGroup rds.DBSubnetGroup var providers []*schema.Provider @@ -1103,6 +1231,10 @@ func TestAccRDSInstance_ReplicateSourceDBDBSubnetGroupName_ramShared(t *testing. } func TestAccRDSInstance_ReplicateSourceDBDBSubnetGroupName_vpcSecurityGroupIDs(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance var dbSubnetGroup rds.DBSubnetGroup var providers []*schema.Provider @@ -1181,6 +1313,10 @@ func TestAccRDSInstance_ReplicateSourceDB_deletionProtection(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_iamDatabaseAuthenticationEnabled(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1207,6 +1343,10 @@ func TestAccRDSInstance_ReplicateSourceDB_iamDatabaseAuthenticationEnabled(t *te } func TestAccRDSInstance_ReplicateSourceDB_maintenanceWindow(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1233,6 +1373,10 @@ func TestAccRDSInstance_ReplicateSourceDB_maintenanceWindow(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_maxAllocatedStorage(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1259,6 +1403,10 @@ func TestAccRDSInstance_ReplicateSourceDB_maxAllocatedStorage(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_monitoring(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1285,6 +1433,10 @@ func TestAccRDSInstance_ReplicateSourceDB_monitoring(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_multiAZ(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1311,6 +1463,10 @@ func TestAccRDSInstance_ReplicateSourceDB_multiAZ(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_parameterGroupNameSameSetOnBoth(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1340,6 +1496,10 @@ func TestAccRDSInstance_ReplicateSourceDB_parameterGroupNameSameSetOnBoth(t *tes } func TestAccRDSInstance_ReplicateSourceDB_parameterGroupNameDifferentSetOnBoth(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1369,6 +1529,10 @@ func TestAccRDSInstance_ReplicateSourceDB_parameterGroupNameDifferentSetOnBoth(t } func TestAccRDSInstance_ReplicateSourceDB_parameterGroupNameReplicaCopiesValue(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1397,6 +1561,10 @@ func TestAccRDSInstance_ReplicateSourceDB_parameterGroupNameReplicaCopiesValue(t } func TestAccRDSInstance_ReplicateSourceDB_parameterGroupNameSetOnReplica(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1424,6 +1592,10 @@ func TestAccRDSInstance_ReplicateSourceDB_parameterGroupNameSetOnReplica(t *test } func TestAccRDSInstance_ReplicateSourceDB_port(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1450,6 +1622,10 @@ func TestAccRDSInstance_ReplicateSourceDB_port(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_vpcSecurityGroupIDs(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1476,6 +1652,10 @@ func TestAccRDSInstance_ReplicateSourceDB_vpcSecurityGroupIDs(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_caCertificateIdentifier(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1504,6 +1684,10 @@ func TestAccRDSInstance_ReplicateSourceDB_caCertificateIdentifier(t *testing.T) } func TestAccRDSInstance_ReplicateSourceDB_replicaMode(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1535,6 +1719,10 @@ func TestAccRDSInstance_ReplicateSourceDB_replicaMode(t *testing.T) { // InvalidDBInstanceState: Instance cannot currently reboot due to an in-progress management operation // https://github.com/hashicorp/terraform-provider-aws/issues/11905 func TestAccRDSInstance_ReplicateSourceDB_parameterGroupTwoStep(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1706,6 +1894,10 @@ func TestAccRDSInstance_S3Import_nameGenerated(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_basic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -1745,6 +1937,10 @@ func TestAccRDSInstance_SnapshotIdentifier_basic(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_namePrefix(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance sourceName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1779,6 +1975,10 @@ func TestAccRDSInstance_SnapshotIdentifier_namePrefix(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_nameGenerated(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance sourceName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1812,6 +2012,10 @@ func TestAccRDSInstance_SnapshotIdentifier_nameGenerated(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_AssociationRemoved(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance1, dbInstance2 rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1845,6 +2049,10 @@ func TestAccRDSInstance_SnapshotIdentifier_AssociationRemoved(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_allocatedStorage(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -1873,6 +2081,10 @@ func TestAccRDSInstance_SnapshotIdentifier_allocatedStorage(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_io1Storage(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -1901,6 +2113,10 @@ func TestAccRDSInstance_SnapshotIdentifier_io1Storage(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_allowMajorVersionUpgrade(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -1929,6 +2145,10 @@ func TestAccRDSInstance_SnapshotIdentifier_allowMajorVersionUpgrade(t *testing.T } func TestAccRDSInstance_SnapshotIdentifier_autoMinorVersionUpgrade(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -1957,6 +2177,10 @@ func TestAccRDSInstance_SnapshotIdentifier_autoMinorVersionUpgrade(t *testing.T) } func TestAccRDSInstance_SnapshotIdentifier_availabilityZone(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -1984,6 +2208,10 @@ func TestAccRDSInstance_SnapshotIdentifier_availabilityZone(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_backupRetentionPeriodOverride(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2012,6 +2240,10 @@ func TestAccRDSInstance_SnapshotIdentifier_backupRetentionPeriodOverride(t *test } func TestAccRDSInstance_SnapshotIdentifier_backupRetentionPeriodUnset(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2040,6 +2272,10 @@ func TestAccRDSInstance_SnapshotIdentifier_backupRetentionPeriodUnset(t *testing } func TestAccRDSInstance_SnapshotIdentifier_backupWindow(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2068,6 +2304,10 @@ func TestAccRDSInstance_SnapshotIdentifier_backupWindow(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_dbSubnetGroupName(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot var dbSubnetGroup rds.DBSubnetGroup @@ -2099,6 +2339,10 @@ func TestAccRDSInstance_SnapshotIdentifier_dbSubnetGroupName(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_dbSubnetGroupNameRAMShared(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot var dbSubnetGroup rds.DBSubnetGroup @@ -2135,6 +2379,10 @@ func TestAccRDSInstance_SnapshotIdentifier_dbSubnetGroupNameRAMShared(t *testing } func TestAccRDSInstance_SnapshotIdentifier_dbSubnetGroupNameVPCSecurityGroupIDs(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot var dbSubnetGroup rds.DBSubnetGroup @@ -2166,6 +2414,10 @@ func TestAccRDSInstance_SnapshotIdentifier_dbSubnetGroupNameVPCSecurityGroupIDs( } func TestAccRDSInstance_SnapshotIdentifier_deletionProtection(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2204,6 +2456,10 @@ func TestAccRDSInstance_SnapshotIdentifier_deletionProtection(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_iamDatabaseAuthenticationEnabled(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2232,6 +2488,10 @@ func TestAccRDSInstance_SnapshotIdentifier_iamDatabaseAuthenticationEnabled(t *t } func TestAccRDSInstance_SnapshotIdentifier_maintenanceWindow(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2260,6 +2520,10 @@ func TestAccRDSInstance_SnapshotIdentifier_maintenanceWindow(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_maxAllocatedStorage(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2288,6 +2552,10 @@ func TestAccRDSInstance_SnapshotIdentifier_maxAllocatedStorage(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_monitoring(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2316,6 +2584,10 @@ func TestAccRDSInstance_SnapshotIdentifier_monitoring(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_multiAZ(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2344,6 +2616,10 @@ func TestAccRDSInstance_SnapshotIdentifier_multiAZ(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_multiAZSQLServer(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2372,6 +2648,10 @@ func TestAccRDSInstance_SnapshotIdentifier_multiAZSQLServer(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_parameterGroupName(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2401,6 +2681,10 @@ func TestAccRDSInstance_SnapshotIdentifier_parameterGroupName(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_port(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2429,6 +2713,10 @@ func TestAccRDSInstance_SnapshotIdentifier_port(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_tags(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2490,6 +2778,10 @@ func TestAccRDSInstance_SnapshotIdentifier_tagsRemove(t *testing.T) { } func TestAccRDSInstance_SnapshotIdentifier_vpcSecurityGroupIDs(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2521,6 +2813,10 @@ func TestAccRDSInstance_SnapshotIdentifier_vpcSecurityGroupIDs(t *testing.T) { // vpc_security_group_ids is set (which triggered the resource update function), // and tags is set which was missing its ARN used for tagging func TestAccRDSInstance_SnapshotIdentifier_vpcSecurityGroupIDsTags(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -2550,6 +2846,10 @@ func TestAccRDSInstance_SnapshotIdentifier_vpcSecurityGroupIDsTags(t *testing.T) } func TestAccRDSInstance_monitoringInterval(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance resourceName := "aws_db_instance.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -2604,6 +2904,10 @@ func TestAccRDSInstance_monitoringInterval(t *testing.T) { } func TestAccRDSInstance_MonitoringRoleARN_enabledToDisabled(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance iamRoleResourceName := "aws_iam_role.test" resourceName := "aws_db_instance.test" @@ -2645,6 +2949,10 @@ func TestAccRDSInstance_MonitoringRoleARN_enabledToDisabled(t *testing.T) { } func TestAccRDSInstance_MonitoringRoleARN_enabledToRemoved(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance iamRoleResourceName := "aws_iam_role.test" resourceName := "aws_db_instance.test" @@ -2685,6 +2993,10 @@ func TestAccRDSInstance_MonitoringRoleARN_enabledToRemoved(t *testing.T) { } func TestAccRDSInstance_MonitoringRoleARN_removedToEnabled(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance iamRoleResourceName := "aws_iam_role.test" resourceName := "aws_db_instance.test" @@ -2728,6 +3040,10 @@ func TestAccRDSInstance_MonitoringRoleARN_removedToEnabled(t *testing.T) { // We apply a plan, then change just the iops. If the apply succeeds, we // consider this a pass, as before in 3760 the request would fail func TestAccRDSInstance_separateIopsUpdate(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -2758,6 +3074,10 @@ func TestAccRDSInstance_separateIopsUpdate(t *testing.T) { } func TestAccRDSInstance_portUpdate(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -2789,6 +3109,10 @@ func TestAccRDSInstance_portUpdate(t *testing.T) { } func TestAccRDSInstance_MSSQL_tz(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_instance.test" @@ -2823,6 +3147,10 @@ func TestAccRDSInstance_MSSQL_tz(t *testing.T) { } func TestAccRDSInstance_MSSQL_domain(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var vBefore, vAfter rds.DBInstance resourceName := "aws_db_instance.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -2860,6 +3188,14 @@ func TestAccRDSInstance_MSSQL_domain(t *testing.T) { } func TestAccRDSInstance_MSSQL_domainSnapshotRestore(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v, vRestoredInstance rds.DBInstance resourceName := "aws_db_instance.test" originResourceName := "aws_db_instance.origin" @@ -2888,6 +3224,10 @@ func TestAccRDSInstance_MSSQL_domainSnapshotRestore(t *testing.T) { } func TestAccRDSInstance_MySQL_snapshotRestoreWithEngineVersion(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v, vRestoredInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_instance.test" @@ -2914,6 +3254,10 @@ func TestAccRDSInstance_MySQL_snapshotRestoreWithEngineVersion(t *testing.T) { } func TestAccRDSInstance_minorVersion(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -2955,6 +3299,10 @@ func TestAccRDSInstance_ec2Classic(t *testing.T) { } func TestAccRDSInstance_cloudWatchLogsExport(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -2988,6 +3336,10 @@ func TestAccRDSInstance_cloudWatchLogsExport(t *testing.T) { } func TestAccRDSInstance_EnabledCloudWatchLogsExports_mySQL(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBInstance resourceName := "aws_db_instance.bar" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -3039,6 +3391,10 @@ func TestAccRDSInstance_EnabledCloudWatchLogsExports_mySQL(t *testing.T) { } func TestAccRDSInstance_EnabledCloudWatchLogsExports_msSQL(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -3073,6 +3429,10 @@ func TestAccRDSInstance_EnabledCloudWatchLogsExports_msSQL(t *testing.T) { } func TestAccRDSInstance_EnabledCloudWatchLogsExports_oracle(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -3108,6 +3468,10 @@ func TestAccRDSInstance_EnabledCloudWatchLogsExports_oracle(t *testing.T) { } func TestAccRDSInstance_EnabledCloudWatchLogsExports_postgresql(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -3143,6 +3507,10 @@ func TestAccRDSInstance_EnabledCloudWatchLogsExports_postgresql(t *testing.T) { } func TestAccRDSInstance_noDeleteAutomatedBackups(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -3495,6 +3863,10 @@ func testAccCheckInstanceEC2ClassicExists(resourceName string, v *rds.DBInstance // Reference: https://github.com/hashicorp/terraform-provider-aws/issues/8792 func TestAccRDSInstance_PerformanceInsightsEnabled_disabledToEnabled(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_instance.test" @@ -3534,6 +3906,10 @@ func TestAccRDSInstance_PerformanceInsightsEnabled_disabledToEnabled(t *testing. } func TestAccRDSInstance_PerformanceInsightsEnabled_enabledToDisabled(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_instance.test" @@ -3573,6 +3949,10 @@ func TestAccRDSInstance_PerformanceInsightsEnabled_enabledToDisabled(t *testing. } func TestAccRDSInstance_performanceInsightsKMSKeyID(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) kmsKeyResourceName := "aws_kms_key.test" @@ -3623,6 +4003,10 @@ func TestAccRDSInstance_performanceInsightsKMSKeyID(t *testing.T) { } func TestAccRDSInstance_performanceInsightsRetentionPeriod(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_instance.test" @@ -3664,6 +4048,10 @@ func TestAccRDSInstance_performanceInsightsRetentionPeriod(t *testing.T) { } func TestAccRDSInstance_ReplicateSourceDB_performanceInsightsEnabled(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -3693,6 +4081,10 @@ func TestAccRDSInstance_ReplicateSourceDB_performanceInsightsEnabled(t *testing. } func TestAccRDSInstance_SnapshotIdentifier_performanceInsightsEnabled(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance var dbSnapshot rds.DBSnapshot @@ -3724,6 +4116,10 @@ func TestAccRDSInstance_SnapshotIdentifier_performanceInsightsEnabled(t *testing } func TestAccRDSInstance_caCertificateIdentifier(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance resourceName := "aws_db_instance.bar" @@ -3747,6 +4143,10 @@ func TestAccRDSInstance_caCertificateIdentifier(t *testing.T) { } func TestAccRDSInstance_RestoreToPointInTime_sourceIdentifier(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance sourceName := "aws_db_instance.test" resourceName := "aws_db_instance.restore" @@ -3784,6 +4184,10 @@ func TestAccRDSInstance_RestoreToPointInTime_sourceIdentifier(t *testing.T) { } func TestAccRDSInstance_RestoreToPointInTime_sourceResourceID(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance, sourceDbInstance rds.DBInstance sourceName := "aws_db_instance.test" resourceName := "aws_db_instance.restore" @@ -3821,6 +4225,10 @@ func TestAccRDSInstance_RestoreToPointInTime_sourceResourceID(t *testing.T) { } func TestAccRDSInstance_NationalCharacterSet_oracle(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -3856,6 +4264,10 @@ func TestAccRDSInstance_NationalCharacterSet_oracle(t *testing.T) { } func TestAccRDSInstance_NoNationalCharacterSet_oracle(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -4059,6 +4471,10 @@ func TestAccRDSInstance_CoIPEnabled_snapshotIdentifier(t *testing.T) { } func TestAccRDSInstance_license(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbInstance1 rds.DBInstance rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_instance.test" diff --git a/internal/service/rds/option_group_test.go b/internal/service/rds/option_group_test.go index 658c29d44b3..796b1c11bce 100644 --- a/internal/service/rds/option_group_test.go +++ b/internal/service/rds/option_group_test.go @@ -158,6 +158,10 @@ func TestAccRDSOptionGroup_optionGroupDescription(t *testing.T) { } func TestAccRDSOptionGroup_basicDestroyWithInstance(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_option_group.test" diff --git a/internal/service/rds/orderable_instance_data_source_test.go b/internal/service/rds/orderable_instance_data_source_test.go index 586dea7dd56..867337cc444 100644 --- a/internal/service/rds/orderable_instance_data_source_test.go +++ b/internal/service/rds/orderable_instance_data_source_test.go @@ -38,6 +38,10 @@ func TestAccRDSOrderableInstanceDataSource_basic(t *testing.T) { } func TestAccRDSOrderableInstanceDataSource_preferredClass(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + dataSourceName := "data.aws_rds_orderable_db_instance.test" preferredClass := "db.t3.micro" @@ -58,6 +62,10 @@ func TestAccRDSOrderableInstanceDataSource_preferredClass(t *testing.T) { } func TestAccRDSOrderableInstanceDataSource_preferredVersion(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + dataSourceName := "data.aws_rds_orderable_db_instance.test" resource.ParallelTest(t, resource.TestCase{ @@ -77,6 +85,10 @@ func TestAccRDSOrderableInstanceDataSource_preferredVersion(t *testing.T) { } func TestAccRDSOrderableInstanceDataSource_preferredClassAndVersion(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + dataSourceName := "data.aws_rds_orderable_db_instance.test" resource.ParallelTest(t, resource.TestCase{ @@ -97,6 +109,10 @@ func TestAccRDSOrderableInstanceDataSource_preferredClassAndVersion(t *testing.T } func TestAccRDSOrderableInstanceDataSource_supportsEnhancedMonitoring(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + dataSourceName := "data.aws_rds_orderable_db_instance.test" resource.ParallelTest(t, resource.TestCase{ @@ -116,6 +132,10 @@ func TestAccRDSOrderableInstanceDataSource_supportsEnhancedMonitoring(t *testing } func TestAccRDSOrderableInstanceDataSource_supportsIAMDatabaseAuthentication(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + dataSourceName := "data.aws_rds_orderable_db_instance.test" resource.ParallelTest(t, resource.TestCase{ @@ -135,6 +155,10 @@ func TestAccRDSOrderableInstanceDataSource_supportsIAMDatabaseAuthentication(t * } func TestAccRDSOrderableInstanceDataSource_supportsIops(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + dataSourceName := "data.aws_rds_orderable_db_instance.test" resource.ParallelTest(t, resource.TestCase{ @@ -154,6 +178,10 @@ func TestAccRDSOrderableInstanceDataSource_supportsIops(t *testing.T) { } func TestAccRDSOrderableInstanceDataSource_supportsKerberosAuthentication(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + dataSourceName := "data.aws_rds_orderable_db_instance.test" resource.ParallelTest(t, resource.TestCase{ @@ -173,6 +201,10 @@ func TestAccRDSOrderableInstanceDataSource_supportsKerberosAuthentication(t *tes } func TestAccRDSOrderableInstanceDataSource_supportsPerformanceInsights(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + dataSourceName := "data.aws_rds_orderable_db_instance.test" resource.ParallelTest(t, resource.TestCase{ @@ -196,6 +228,10 @@ func TestAccRDSOrderableInstanceDataSource_supportsPerformanceInsights(t *testin } func TestAccRDSOrderableInstanceDataSource_supportsStorageAutoScaling(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + dataSourceName := "data.aws_rds_orderable_db_instance.test" resource.ParallelTest(t, resource.TestCase{ @@ -215,6 +251,10 @@ func TestAccRDSOrderableInstanceDataSource_supportsStorageAutoScaling(t *testing } func TestAccRDSOrderableInstanceDataSource_supportsStorageEncryption(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + dataSourceName := "data.aws_rds_orderable_db_instance.test" resource.ParallelTest(t, resource.TestCase{ diff --git a/internal/service/rds/proxy_data_source_test.go b/internal/service/rds/proxy_data_source_test.go index 20059796af2..a0c3fc654d0 100644 --- a/internal/service/rds/proxy_data_source_test.go +++ b/internal/service/rds/proxy_data_source_test.go @@ -11,6 +11,10 @@ import ( ) func TestAccRDSProxyDataSource_basic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + dataSourceName := "data.aws_db_proxy.test" resourceName := "aws_db_proxy.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) diff --git a/internal/service/rds/proxy_default_target_group_test.go b/internal/service/rds/proxy_default_target_group_test.go index 2b32dfea5c8..fb7c9558837 100644 --- a/internal/service/rds/proxy_default_target_group_test.go +++ b/internal/service/rds/proxy_default_target_group_test.go @@ -17,6 +17,10 @@ import ( ) func TestAccRDSProxyDefaultTargetGroup_basic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxyTargetGroup rds.DBProxyTargetGroup resourceName := "aws_db_proxy_default_target_group.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -52,6 +56,10 @@ func TestAccRDSProxyDefaultTargetGroup_basic(t *testing.T) { } func TestAccRDSProxyDefaultTargetGroup_emptyConnectionPool(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxyTargetGroup rds.DBProxyTargetGroup resourceName := "aws_db_proxy_default_target_group.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -87,6 +95,10 @@ func TestAccRDSProxyDefaultTargetGroup_emptyConnectionPool(t *testing.T) { } func TestAccRDSProxyDefaultTargetGroup_connectionBorrowTimeout(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxyTargetGroup rds.DBProxyTargetGroup resourceName := "aws_db_proxy_default_target_group.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -121,6 +133,10 @@ func TestAccRDSProxyDefaultTargetGroup_connectionBorrowTimeout(t *testing.T) { } func TestAccRDSProxyDefaultTargetGroup_initQuery(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxyTargetGroup rds.DBProxyTargetGroup resourceName := "aws_db_proxy_default_target_group.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -155,6 +171,10 @@ func TestAccRDSProxyDefaultTargetGroup_initQuery(t *testing.T) { } func TestAccRDSProxyDefaultTargetGroup_maxConnectionsPercent(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxyTargetGroup rds.DBProxyTargetGroup resourceName := "aws_db_proxy_default_target_group.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -189,6 +209,10 @@ func TestAccRDSProxyDefaultTargetGroup_maxConnectionsPercent(t *testing.T) { } func TestAccRDSProxyDefaultTargetGroup_maxIdleConnectionsPercent(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxyTargetGroup rds.DBProxyTargetGroup resourceName := "aws_db_proxy_default_target_group.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -223,6 +247,10 @@ func TestAccRDSProxyDefaultTargetGroup_maxIdleConnectionsPercent(t *testing.T) { } func TestAccRDSProxyDefaultTargetGroup_sessionPinningFilters(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxyTargetGroup rds.DBProxyTargetGroup resourceName := "aws_db_proxy_default_target_group.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -259,6 +287,10 @@ func TestAccRDSProxyDefaultTargetGroup_sessionPinningFilters(t *testing.T) { } func TestAccRDSProxyDefaultTargetGroup_disappears(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBProxy dbProxyResourceName := "aws_db_proxy.test" resourceName := "aws_db_proxy_default_target_group.test" diff --git a/internal/service/rds/proxy_endpoint_test.go b/internal/service/rds/proxy_endpoint_test.go index 4950ec2fb32..cbd7fb9a7fc 100644 --- a/internal/service/rds/proxy_endpoint_test.go +++ b/internal/service/rds/proxy_endpoint_test.go @@ -16,6 +16,10 @@ import ( ) func TestAccRDSProxyEndpoint_basic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBProxyEndpoint resourceName := "aws_db_proxy_endpoint.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -54,6 +58,10 @@ func TestAccRDSProxyEndpoint_basic(t *testing.T) { } func TestAccRDSProxyEndpoint_targetRole(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBProxyEndpoint resourceName := "aws_db_proxy_endpoint.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -81,6 +89,10 @@ func TestAccRDSProxyEndpoint_targetRole(t *testing.T) { } func TestAccRDSProxyEndpoint_vpcSecurityGroupIDs(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxy rds.DBProxyEndpoint resourceName := "aws_db_proxy_endpoint.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -118,6 +130,10 @@ func TestAccRDSProxyEndpoint_vpcSecurityGroupIDs(t *testing.T) { } func TestAccRDSProxyEndpoint_tags(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxy rds.DBProxyEndpoint resourceName := "aws_db_proxy_endpoint.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -163,6 +179,10 @@ func TestAccRDSProxyEndpoint_tags(t *testing.T) { } func TestAccRDSProxyEndpoint_disappears(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBProxyEndpoint resourceName := "aws_db_proxy_endpoint.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -185,6 +205,10 @@ func TestAccRDSProxyEndpoint_disappears(t *testing.T) { } func TestAccRDSProxyEndpoint_Disappears_proxy(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBProxyEndpoint resourceName := "aws_db_proxy_endpoint.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) diff --git a/internal/service/rds/proxy_target_test.go b/internal/service/rds/proxy_target_test.go index fdff5dba7f5..130ad3287a7 100644 --- a/internal/service/rds/proxy_target_test.go +++ b/internal/service/rds/proxy_target_test.go @@ -15,6 +15,10 @@ import ( ) func TestAccRDSProxyTarget_instance(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxyTarget rds.DBProxyTarget resourceName := "aws_db_proxy_target.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -47,6 +51,10 @@ func TestAccRDSProxyTarget_instance(t *testing.T) { } func TestAccRDSProxyTarget_cluster(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxyTarget rds.DBProxyTarget resourceName := "aws_db_proxy_target.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -79,6 +87,10 @@ func TestAccRDSProxyTarget_cluster(t *testing.T) { } func TestAccRDSProxyTarget_disappears(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxyTarget rds.DBProxyTarget resourceName := "aws_db_proxy_target.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) diff --git a/internal/service/rds/proxy_test.go b/internal/service/rds/proxy_test.go index 54805bb5632..a82436edc39 100644 --- a/internal/service/rds/proxy_test.go +++ b/internal/service/rds/proxy_test.go @@ -17,6 +17,10 @@ import ( ) func TestAccRDSProxy_basic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBProxy resourceName := "aws_db_proxy.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -59,6 +63,10 @@ func TestAccRDSProxy_basic(t *testing.T) { } func TestAccRDSProxy_name(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxy rds.DBProxy resourceName := "aws_db_proxy.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -94,6 +102,10 @@ func TestAccRDSProxy_name(t *testing.T) { } func TestAccRDSProxy_debugLogging(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxy rds.DBProxy resourceName := "aws_db_proxy.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -128,6 +140,10 @@ func TestAccRDSProxy_debugLogging(t *testing.T) { } func TestAccRDSProxy_idleClientTimeout(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxy rds.DBProxy resourceName := "aws_db_proxy.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -162,6 +178,10 @@ func TestAccRDSProxy_idleClientTimeout(t *testing.T) { } func TestAccRDSProxy_requireTLS(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxy rds.DBProxy resourceName := "aws_db_proxy.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -196,6 +216,10 @@ func TestAccRDSProxy_requireTLS(t *testing.T) { } func TestAccRDSProxy_roleARN(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxy rds.DBProxy resourceName := "aws_db_proxy.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -231,6 +255,10 @@ func TestAccRDSProxy_roleARN(t *testing.T) { } func TestAccRDSProxy_vpcSecurityGroupIDs(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxy rds.DBProxy resourceName := "aws_db_proxy.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -268,6 +296,10 @@ func TestAccRDSProxy_vpcSecurityGroupIDs(t *testing.T) { } func TestAccRDSProxy_authDescription(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxy rds.DBProxy resourceName := "aws_db_proxy.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -303,6 +335,10 @@ func TestAccRDSProxy_authDescription(t *testing.T) { } func TestAccRDSProxy_authIAMAuth(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxy rds.DBProxy resourceName := "aws_db_proxy.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -338,6 +374,10 @@ func TestAccRDSProxy_authIAMAuth(t *testing.T) { } func TestAccRDSProxy_authSecretARN(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxy rds.DBProxy resourceName := "aws_db_proxy.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -373,6 +413,10 @@ func TestAccRDSProxy_authSecretARN(t *testing.T) { } func TestAccRDSProxy_tags(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var dbProxy rds.DBProxy resourceName := "aws_db_proxy.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -409,6 +453,10 @@ func TestAccRDSProxy_tags(t *testing.T) { } func TestAccRDSProxy_disappears(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBProxy resourceName := "aws_db_proxy.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) diff --git a/internal/service/rds/snapshot_data_source_test.go b/internal/service/rds/snapshot_data_source_test.go index b7f386d9f4d..5dfb58744ca 100644 --- a/internal/service/rds/snapshot_data_source_test.go +++ b/internal/service/rds/snapshot_data_source_test.go @@ -12,6 +12,10 @@ import ( ) func TestAccRDSSnapshotDataSource_basic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + rInt := sdkacctest.RandInt() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, diff --git a/internal/service/rds/snapshot_test.go b/internal/service/rds/snapshot_test.go index 7e88039110f..845ec5b94f0 100644 --- a/internal/service/rds/snapshot_test.go +++ b/internal/service/rds/snapshot_test.go @@ -16,6 +16,10 @@ import ( ) func TestAccRDSSnapshot_basic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBSnapshot resourceName := "aws_db_snapshot.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -44,6 +48,10 @@ func TestAccRDSSnapshot_basic(t *testing.T) { } func TestAccRDSSnapshot_tags(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBSnapshot resourceName := "aws_db_snapshot.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -89,6 +97,10 @@ func TestAccRDSSnapshot_tags(t *testing.T) { } func TestAccRDSSnapshot_disappears(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var v rds.DBSnapshot rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_db_snapshot.test" From 2c8e5da31b534852a2783a4eb2eea61e6a0116e9 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 14 Mar 2022 14:28:34 -0400 Subject: [PATCH 222/229] rds_global_cluster: Allow better config timeout use --- internal/service/rds/global_cluster.go | 26 +++++++++++++------------- internal/service/rds/wait.go | 2 -- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index fd45ed01482..8aa476a94a1 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -224,7 +224,7 @@ func resourceGlobalClusterUpdate(d *schema.ResourceData, meta interface{}) error } if d.HasChange("engine_version") { - if err := globalClusterUpgradeEngineVersion(d, meta); err != nil { + if err := globalClusterUpgradeEngineVersion(d, meta, d.Timeout(schema.TimeoutUpdate)); err != nil { return err } } @@ -518,7 +518,7 @@ func waitForGlobalClusterRemoval(conn *rds.RDS, dbClusterIdentifier string, time return nil } -func globalClusterUpgradeMajorEngineVersion(meta interface{}, clusterID string, engineVersion string) error { +func globalClusterUpgradeMajorEngineVersion(meta interface{}, clusterID string, engineVersion string, timeout time.Duration) error { conn := meta.(*conns.AWSClient).RDSConn input := &rds.ModifyGlobalClusterInput{ @@ -528,7 +528,7 @@ func globalClusterUpgradeMajorEngineVersion(meta interface{}, clusterID string, input.AllowMajorVersionUpgrade = aws.Bool(true) input.EngineVersion = aws.String(engineVersion) - err := resource.Retry(clusterInitiateUpgradeTimeout, func() *resource.RetryError { + err := resource.Retry(timeout, func() *resource.RetryError { _, err := conn.ModifyGlobalCluster(input) if err != nil { @@ -536,7 +536,7 @@ func globalClusterUpgradeMajorEngineVersion(meta interface{}, clusterID string, return resource.NonRetryableError(err) } - if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "ModifyGlobalCluster only supports Major Version Upgrades. To patch the members of your global cluster to a newer minor version you need to call ModifyDbCluster in each one of them.") { + if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "only supports Major Version Upgrades") { return resource.NonRetryableError(err) } @@ -583,7 +583,7 @@ func globalClusterUpgradeMajorEngineVersion(meta interface{}, clusterID string, useConn = rds.New(meta.(*conns.AWSClient).Session, aws.NewConfig().WithRegion(clusterRegion)) } - if err := waitForClusterUpdate(useConn, dbi, clusterInitiateUpgradeTimeout); err != nil { + if err := waitForClusterUpdate(useConn, dbi, timeout); err != nil { return fmt.Errorf("failed to update engine_version, waiting for RDS Global Cluster (%s) to update: %s", dbi, err) } } @@ -617,7 +617,7 @@ func ClusterIDRegionFromARN(arnID string) (string, string, error) { return dbi, parsedARN.Region, nil } -func globalClusterUpgradeMinorEngineVersion(meta interface{}, clusterMembers *schema.Set, clusterID, engineVersion string) error { +func globalClusterUpgradeMinorEngineVersion(meta interface{}, clusterMembers *schema.Set, clusterID, engineVersion string, timeout time.Duration) error { conn := meta.(*conns.AWSClient).RDSConn log.Printf("[INFO] Performing RDS Global Cluster (%s) minor version (%s) upgrade", clusterID, engineVersion) @@ -657,7 +657,7 @@ func globalClusterUpgradeMinorEngineVersion(meta interface{}, clusterMembers *sc log.Printf("[INFO] Performing RDS Global Cluster (%s) Cluster (%s) minor version (%s) upgrade", clusterID, dbi, engineVersion) - err = resource.Retry(clusterInitiateUpgradeTimeout, func() *resource.RetryError { + err = resource.Retry(timeout, func() *resource.RetryError { _, err := useConn.ModifyDBCluster(modInput) if err != nil { @@ -691,7 +691,7 @@ func globalClusterUpgradeMinorEngineVersion(meta interface{}, clusterMembers *sc } log.Printf("[INFO] Waiting for RDS Global Cluster (%s) Cluster (%s) minor version (%s) upgrade", clusterID, dbi, engineVersion) - if err := waitForClusterUpdate(useConn, dbi, clusterInitiateUpgradeTimeout); err != nil { + if err := waitForClusterUpdate(useConn, dbi, timeout); err != nil { return fmt.Errorf("failed to update engine_version, waiting for RDS Global Cluster Cluster (%s) to update: %s", dbi, err) } } @@ -712,19 +712,19 @@ func globalClusterUpgradeMinorEngineVersion(meta interface{}, clusterMembers *sc if aws.StringValue(globalCluster.EngineVersion) != engineVersion { log.Printf("[DEBUG] RDS Global Cluster (%s) upgrade did not take effect, trying again", clusterID) - return globalClusterUpgradeMinorEngineVersion(meta, clusterMembers, clusterID, engineVersion) + return globalClusterUpgradeMinorEngineVersion(meta, clusterMembers, clusterID, engineVersion, timeout) } return nil } -func globalClusterUpgradeEngineVersion(d *schema.ResourceData, meta interface{}) error { +func globalClusterUpgradeEngineVersion(d *schema.ResourceData, meta interface{}, timeout time.Duration) error { log.Printf("[DEBUG] Upgrading RDS Global Cluster (%s) engine version: %s", d.Id(), d.Get("engine_version")) - err := globalClusterUpgradeMajorEngineVersion(meta, d.Id(), d.Get("engine_version").(string)) + err := globalClusterUpgradeMajorEngineVersion(meta, d.Id(), d.Get("engine_version").(string), timeout) - if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "ModifyGlobalCluster only supports Major Version Upgrades. To patch the members of your global cluster to a newer minor version you need to call ModifyDbCluster in each one of them.") { - err = globalClusterUpgradeMinorEngineVersion(meta, d.Get("global_cluster_members").(*schema.Set), d.Id(), d.Get("engine_version").(string)) + if tfawserr.ErrMessageContains(err, "InvalidParameterValue", "only supports Major Version Upgrades") { + err = globalClusterUpgradeMinorEngineVersion(meta, d.Get("global_cluster_members").(*schema.Set), d.Id(), d.Get("engine_version").(string), timeout) if err != nil { return fmt.Errorf("while upgrading minor version of RDS Global Cluster (%s): %w", d.Id(), err) diff --git a/internal/service/rds/wait.go b/internal/service/rds/wait.go index 2450b406f6a..6751a4d048d 100644 --- a/internal/service/rds/wait.go +++ b/internal/service/rds/wait.go @@ -8,8 +8,6 @@ import ( ) const ( - clusterInitiateUpgradeTimeout = 30 * time.Minute - dbClusterRoleAssociationCreatedTimeout = 5 * time.Minute dbClusterRoleAssociationDeletedTimeout = 5 * time.Minute ) From f539a8c1db7afa84e1c1c7f42e7e88ab7835b837 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 14 Mar 2022 14:31:59 -0400 Subject: [PATCH 223/229] rds_global_cluster: Increase update default timeout --- internal/service/rds/global_cluster.go | 2 +- website/docs/r/rds_global_cluster.html.markdown | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/rds/global_cluster.go b/internal/service/rds/global_cluster.go index 8aa476a94a1..a2d98929268 100644 --- a/internal/service/rds/global_cluster.go +++ b/internal/service/rds/global_cluster.go @@ -21,7 +21,7 @@ import ( const ( GlobalClusterRemovalTimeout = 30 * time.Minute globalClusterCreateTimeout = 30 * time.Minute - globalClusterUpdateTimeout = 60 * time.Minute + globalClusterUpdateTimeout = 90 * time.Minute ) func ResourceGlobalCluster() *schema.Resource { diff --git a/website/docs/r/rds_global_cluster.html.markdown b/website/docs/r/rds_global_cluster.html.markdown index ccb51211999..bf2cfd3c6a8 100644 --- a/website/docs/r/rds_global_cluster.html.markdown +++ b/website/docs/r/rds_global_cluster.html.markdown @@ -230,7 +230,7 @@ In addition to all arguments above, the following attributes are exported: [Timeouts](https://www.terraform.io/docs/configuration/blocks/resources/syntax.html#operation-timeouts) configuration options: - `create` - (Default `30 minutes`) -- `update` - (Default `30 minutes`) +- `update` - (Default `90 minutes`) - `delete` - (Default `30 minutes`) ## Import From f8a28ca55e585257f8e043961ea795cf6f6fbe04 Mon Sep 17 00:00:00 2001 From: changelogbot Date: Mon, 14 Mar 2022 19:35:22 +0000 Subject: [PATCH 224/229] Update CHANGELOG.md for #23560 --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35492371c43..9308fd5e57d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ FEATURES: * **New Data Source:** `aws_networkmanager_links` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) * **New Data Source:** `aws_networkmanager_site` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) * **New Data Source:** `aws_networkmanager_sites` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* **New Resource:** `aws_gamelift_game_server_group` ([#23606](https://github.com/hashicorp/terraform-provider-aws/issues/23606)) * **New Resource:** `aws_networkmanager_connection` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) * **New Resource:** `aws_networkmanager_customer_gateway_association` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) * **New Resource:** `aws_networkmanager_device` ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) @@ -27,7 +28,19 @@ ENHANCEMENTS: * data-source/aws_ec2_transit_gateway_connect_peer: Add `arn` attribute ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) * data_source/aws_redshift_cluster: Add `availability_zone_relocation_enabled` attribute. ([#20812](https://github.com/hashicorp/terraform-provider-aws/issues/20812)) * resource/aws_ec2_transit_gateway_connect_peer: Add `arn` attribute ([#13251](https://github.com/hashicorp/terraform-provider-aws/issues/13251)) +* resource/aws_ecs_service: `enable_ecs_managed_tags`, `load_balancer`, `propagate_tags` and `service_registries` can now be updated in-place ([#23600](https://github.com/hashicorp/terraform-provider-aws/issues/23600)) +* resource/aws_iot_topic_rule: Add `cloudwatch_logs` and `error_action.cloudwatch_logs` arguments ([#23440](https://github.com/hashicorp/terraform-provider-aws/issues/23440)) +* resource/aws_msk_configuration: Correctly set `latest_revision` as Computed when `server_properties` changes ([#23662](https://github.com/hashicorp/terraform-provider-aws/issues/23662)) +* resource/aws_rds_global_cluster: Add configurable timeouts ([#23560](https://github.com/hashicorp/terraform-provider-aws/issues/23560)) * resource/aws_redshift_cluster: Add `availability_zone_relocation_enabled` attribute and allow `availability_zone` to be changed in-place. ([#20812](https://github.com/hashicorp/terraform-provider-aws/issues/20812)) +* resource/aws_transfer_server: Add `pre_authentication_login_banner` and `post_authentication_login_banner` arguments ([#23631](https://github.com/hashicorp/terraform-provider-aws/issues/23631)) + +BUG FIXES: + +* resource/aws_amplify_app: Allow `repository` to be updated in-place ([#23517](https://github.com/hashicorp/terraform-provider-aws/issues/23517)) +* resource/aws_db_instance: Fix issues where configured update timeout was not respected, and update would fail if instance were in the process of being configured. ([#23560](https://github.com/hashicorp/terraform-provider-aws/issues/23560)) +* resource/aws_rds_event_subscription: Fix issue where `enabled` was sometimes not updated ([#23560](https://github.com/hashicorp/terraform-provider-aws/issues/23560)) +* resource/aws_rds_global_cluster: Fix ability to perform cluster version upgrades, including of clusters in distinct regions, such as previously got error: "Invalid database cluster identifier" ([#23560](https://github.com/hashicorp/terraform-provider-aws/issues/23560)) ## 4.5.0 (March 11, 2022) From 00a46551f72ea9bcfed9db290006954af1fa0202 Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Sun, 6 Mar 2022 11:49:50 +0100 Subject: [PATCH 225/229] #23475 - Add `mysql` and `postgres` to validEngine func to support Multi-AZ DB clusters --- internal/service/rds/validate.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/service/rds/validate.go b/internal/service/rds/validate.go index e22f7b44cbc..6e3da6ad67e 100644 --- a/internal/service/rds/validate.go +++ b/internal/service/rds/validate.go @@ -148,6 +148,8 @@ func validEngine() schema.SchemaValidateFunc { "aurora", "aurora-mysql", "aurora-postgresql", + "postgres", + "mysql", }, false) } From b9d67e0b3dacdefbfb5bd7645e189bb797eaa44e Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Sun, 6 Mar 2022 14:26:54 +0100 Subject: [PATCH 226/229] #23475 - Add required parameters: storage_type, allocated_storage, iops and db_cluster_instance_class --- internal/service/rds/cluster.go | 62 +++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/internal/service/rds/cluster.go b/internal/service/rds/cluster.go index 32084974fe2..35d34477e2f 100644 --- a/internal/service/rds/cluster.go +++ b/internal/service/rds/cluster.go @@ -157,6 +157,11 @@ func ResourceCluster() *schema.Resource { Computed: true, }, + "db_cluster_instance_class": { + Type: schema.TypeString, + Optional: true, + }, + "engine": { Type: schema.TypeString, Optional: true, @@ -231,6 +236,22 @@ func ResourceCluster() *schema.Resource { }, }, + "allocated_storage": { + Type: schema.TypeInt, + Optional: true, + }, + + "storage_type": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "iops": { + Type: schema.TypeInt, + Optional: true, + }, + "storage_encrypted": { Type: schema.TypeBool, Optional: true, @@ -870,6 +891,10 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { createOpts.DBClusterParameterGroupName = aws.String(attr.(string)) } + if attr, ok := d.GetOk("db_cluster_instance_class"); ok { + createOpts.DBClusterInstanceClass = aws.String(attr.(string)) + } + if attr, ok := d.GetOk("engine_version"); ok { createOpts.EngineVersion = aws.String(attr.(string)) } @@ -922,6 +947,18 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error { createOpts.ReplicationSourceIdentifier = aws.String(attr.(string)) } + if attr, ok := d.GetOkExists("allocated_storage"); ok { + createOpts.AllocatedStorage = aws.Int64(int64(attr.(int))) + } + + if attr, ok := d.GetOkExists("storage_type"); ok { + createOpts.StorageType = aws.String(attr.(string)) + } + + if attr, ok := d.GetOkExists("iops"); ok { + createOpts.Iops = aws.Int64(int64(attr.(int))) + } + if attr, ok := d.GetOkExists("storage_encrypted"); ok { createOpts.StorageEncrypted = aws.Bool(attr.(bool)) } @@ -1075,6 +1112,7 @@ func resourceClusterRead(d *schema.ResourceData, meta interface{}) error { } d.Set("endpoint", dbc.Endpoint) + d.Set("db_cluster_instance_class", dbc.DBClusterInstanceClass) d.Set("engine_mode", dbc.EngineMode) d.Set("engine", dbc.Engine) d.Set("hosted_zone_id", dbc.HostedZoneId) @@ -1102,7 +1140,11 @@ func resourceClusterRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("error setting scaling_configuration: %s", err) } + d.Set("allocated_storage", dbc.AllocatedStorage) + d.Set("storage_type", dbc.StorageType) + d.Set("iops", dbc.Iops) d.Set("storage_encrypted", dbc.StorageEncrypted) + d.Set("enable_http_endpoint", dbc.HttpEndpointEnabled) var vpcg []string @@ -1181,6 +1223,11 @@ func resourceClusterUpdate(d *schema.ResourceData, meta interface{}) error { requestUpdate = true } + if d.HasChange("db_cluster_instance_class") { + req.EngineVersion = aws.String(d.Get("db_cluster_instance_class").(string)) + requestUpdate = true + } + if d.HasChange("engine_version") { req.EngineVersion = aws.String(d.Get("engine_version").(string)) requestUpdate = true @@ -1200,6 +1247,21 @@ func resourceClusterUpdate(d *schema.ResourceData, meta interface{}) error { requestUpdate = true } + if d.HasChange("storage_type") { + req.StorageType = aws.String(d.Get("storage_type").(string)) + requestUpdate = true + } + + if d.HasChange("allocated_storage") { + req.AllocatedStorage = aws.Int64(int64(d.Get("allocated_storage").(int))) + requestUpdate = true + } + + if d.HasChange("iops") { + req.Iops = aws.Int64(int64(d.Get("iops").(int))) + requestUpdate = true + } + if d.HasChange("preferred_backup_window") { req.PreferredBackupWindow = aws.String(d.Get("preferred_backup_window").(string)) requestUpdate = true From 38d2cddcfc5f5648ae83e6e2ce43ad2551541341 Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Sun, 6 Mar 2022 18:51:50 +0100 Subject: [PATCH 227/229] Add acceptance tests for storage_type, allocated_storage, iops and db_cluster_instance_class attributes --- internal/service/rds/cluster_test.go | 176 +++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) diff --git a/internal/service/rds/cluster_test.go b/internal/service/rds/cluster_test.go index 5324b6bcd2f..f556f2f1ac1 100644 --- a/internal/service/rds/cluster_test.go +++ b/internal/service/rds/cluster_test.go @@ -308,6 +308,94 @@ func TestAccRDSCluster_availabilityZones(t *testing.T) { }) } +func TestAccRDSCluster_storageType(t *testing.T) { + var dbCluster rds.DBCluster + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_rds_cluster.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccClusterConfig_StorageType(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckClusterExists(resourceName, &dbCluster), + resource.TestCheckResourceAttr(resourceName, "storage_type", "io1"), + ), + }, + }, + }) +} + +func TestAccRDSCluster_allocatedStorage(t *testing.T) { + var dbCluster rds.DBCluster + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_rds_cluster.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccClusterConfig_AllocatedStorage(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckClusterExists(resourceName, &dbCluster), + resource.TestCheckResourceAttr(resourceName, "allocated_storage", "100"), + ), + }, + }, + }) +} + +func TestAccRDSCluster_iops(t *testing.T) { + var dbCluster rds.DBCluster + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_rds_cluster.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccClusterConfig_Iops(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckClusterExists(resourceName, &dbCluster), + resource.TestCheckResourceAttr(resourceName, "iops", "300"), + ), + }, + }, + }) +} + +func TestAccRDSCluster_dbClusterInstanceClass(t *testing.T) { + var dbCluster rds.DBCluster + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_rds_cluster.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, rds.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckClusterDestroy, + Steps: []resource.TestStep{ + { + Config: testAccClusterConfig_DbClusterInstanceClass(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckClusterExists(resourceName, &dbCluster), + resource.TestCheckResourceAttr(resourceName, "db_cluster_instance_class", "db.r6gd.xlarge"), + ), + }, + }, + }) +} + func TestAccRDSCluster_backtrackWindow(t *testing.T) { var dbCluster rds.DBCluster resourceName := "aws_rds_cluster.test" @@ -2251,6 +2339,94 @@ resource "aws_rds_cluster" "test" { `, rName) } +func testAccClusterConfig_StorageType(rName string) string { + return fmt.Sprintf(` +data "aws_availability_zones" "available" { + state = "available" +} + +resource "aws_rds_cluster" "test" { + apply_immediately = true + availability_zones = [data.aws_availability_zones.available.names[0], data.aws_availability_zones.available.names[1], data.aws_availability_zones.available.names[2]] + cluster_identifier = %q + db_cluster_instance_class = "db.r6gd.xlarge" + engine = "mysql" + storage_type = "io1" + allocated_storage = 100 + iops = 300 + master_password = "mustbeeightcharaters" + master_username = "test" + skip_final_snapshot = true +} +`, rName) +} + +func testAccClusterConfig_AllocatedStorage(rName string) string { + return fmt.Sprintf(` +data "aws_availability_zones" "available" { + state = "available" +} + +resource "aws_rds_cluster" "test" { + apply_immediately = true + availability_zones = [data.aws_availability_zones.available.names[0], data.aws_availability_zones.available.names[1], data.aws_availability_zones.available.names[2]] + cluster_identifier = %q + db_cluster_instance_class = "db.r6gd.xlarge" + engine = "mysql" + storage_type = "io1" + allocated_storage = 100 + iops = 300 + master_password = "mustbeeightcharaters" + master_username = "test" + skip_final_snapshot = true +} +`, rName) +} + +func testAccClusterConfig_Iops(rName string) string { + return fmt.Sprintf(` +data "aws_availability_zones" "available" { + state = "available" +} + +resource "aws_rds_cluster" "test" { + apply_immediately = true + availability_zones = [data.aws_availability_zones.available.names[0], data.aws_availability_zones.available.names[1], data.aws_availability_zones.available.names[2]] + cluster_identifier = %q + db_cluster_instance_class = "db.r6gd.xlarge" + engine = "mysql" + storage_type = "io1" + allocated_storage = 100 + iops = 300 + master_password = "mustbeeightcharaters" + master_username = "test" + skip_final_snapshot = true +} +`, rName) +} + +func testAccClusterConfig_DbClusterInstanceClass(rName string) string { + return fmt.Sprintf(` +data "aws_availability_zones" "available" { + state = "available" +} + +resource "aws_rds_cluster" "test" { + apply_immediately = true + availability_zones = [data.aws_availability_zones.available.names[0], data.aws_availability_zones.available.names[1], data.aws_availability_zones.available.names[2]] + cluster_identifier = %q + db_cluster_instance_class = "db.r6gd.xlarge" + engine = "mysql" + storage_type = "io1" + allocated_storage = 100 + iops = 300 + master_password = "mustbeeightcharaters" + master_username = "test" + skip_final_snapshot = true +} +`, rName) +} + func testAccClusterConfig_BacktrackWindow(backtrackWindow int) string { return fmt.Sprintf(` resource "aws_rds_cluster" "test" { From c274ff27938bc29196702b682645a5784cf6cdf8 Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Tue, 15 Mar 2022 09:35:52 +0100 Subject: [PATCH 228/229] Create 23533.txt --- .changelog/23533.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/23533.txt diff --git a/.changelog/23533.txt b/.changelog/23533.txt new file mode 100644 index 00000000000..8a2219f72ff --- /dev/null +++ b/.changelog/23533.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_rds_cluster: Add Multi-AZ support for MySQL and PostgreSQL RDS clusters +``` From cdca52cb84cd769e379045a74ccf47a93bc352db Mon Sep 17 00:00:00 2001 From: Bruno Schaatsbergen Date: Tue, 15 Mar 2022 09:36:46 +0100 Subject: [PATCH 229/229] Set iops to minimum value in acceptance tests --- internal/service/rds/cluster_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/service/rds/cluster_test.go b/internal/service/rds/cluster_test.go index f556f2f1ac1..ec76b8a9337 100644 --- a/internal/service/rds/cluster_test.go +++ b/internal/service/rds/cluster_test.go @@ -2353,7 +2353,7 @@ resource "aws_rds_cluster" "test" { engine = "mysql" storage_type = "io1" allocated_storage = 100 - iops = 300 + iops = 1000 master_password = "mustbeeightcharaters" master_username = "test" skip_final_snapshot = true @@ -2375,7 +2375,7 @@ resource "aws_rds_cluster" "test" { engine = "mysql" storage_type = "io1" allocated_storage = 100 - iops = 300 + iops = 1000 master_password = "mustbeeightcharaters" master_username = "test" skip_final_snapshot = true @@ -2397,7 +2397,7 @@ resource "aws_rds_cluster" "test" { engine = "mysql" storage_type = "io1" allocated_storage = 100 - iops = 300 + iops = 1000 master_password = "mustbeeightcharaters" master_username = "test" skip_final_snapshot = true @@ -2419,7 +2419,7 @@ resource "aws_rds_cluster" "test" { engine = "mysql" storage_type = "io1" allocated_storage = 100 - iops = 300 + iops = 1000 master_password = "mustbeeightcharaters" master_username = "test" skip_final_snapshot = true