diff --git a/.changelog/34319.txt b/.changelog/34319.txt new file mode 100644 index 000000000000..b92ecc7db5fc --- /dev/null +++ b/.changelog/34319.txt @@ -0,0 +1,3 @@ +```release-note:bug +provider: Fix `Value Conversion Error` panic for certain resources when `null` tag values are specified +``` diff --git a/internal/framework/flex/map_test.go b/internal/framework/flex/map_test.go index 5fcd775e0b51..bd5c9fc3461b 100644 --- a/internal/framework/flex/map_test.go +++ b/internal/framework/flex/map_test.go @@ -50,6 +50,16 @@ func TestExpandFrameworkStringMap(t *testing.T) { }), expected: nil, }, + "null element": { + input: types.MapValueMust(types.StringType, map[string]attr.Value{ + "one": types.StringValue("GET"), + "two": types.StringNull(), + }), + expected: map[string]*string{ + "one": aws.String("GET"), + "two": nil, + }, + }, } for name, test := range tests { diff --git a/internal/service/appconfig/application.go b/internal/service/appconfig/application.go index f63b50fffc35..01f19d2af5af 100644 --- a/internal/service/appconfig/application.go +++ b/internal/service/appconfig/application.go @@ -155,11 +155,10 @@ func resourceApplicationDelete(ctx context.Context, d *schema.ResourceData, meta var diags diag.Diagnostics conn := meta.(*conns.AWSClient).AppConfigConn(ctx) - input := &appconfig.DeleteApplicationInput{ + log.Printf("[INFO] Deleting AppConfig Application: %s", d.Id()) + _, err := conn.DeleteApplicationWithContext(ctx, &appconfig.DeleteApplicationInput{ ApplicationId: aws.String(d.Id()), - } - - _, err := conn.DeleteApplicationWithContext(ctx, input) + }) if tfawserr.ErrCodeEquals(err, appconfig.ErrCodeResourceNotFoundException) { return diags diff --git a/internal/service/appconfig/configuration_profile.go b/internal/service/appconfig/configuration_profile.go index 88375c4753e9..3605488f9bc0 100644 --- a/internal/service/appconfig/configuration_profile.go +++ b/internal/service/appconfig/configuration_profile.go @@ -256,17 +256,15 @@ func resourceConfigurationProfileDelete(ctx context.Context, d *schema.ResourceD conn := meta.(*conns.AWSClient).AppConfigConn(ctx) confProfID, appID, err := ConfigurationProfileParseID(d.Id()) - if err != nil { - return sdkdiag.AppendErrorf(diags, "deleting AppConfig Configuration Profile (%s): %s", d.Id(), err) + return sdkdiag.AppendFromErr(diags, err) } - input := &appconfig.DeleteConfigurationProfileInput{ + log.Printf("[INFO] Deleting AppConfig Configuration Profile: %s", d.Id()) + _, err = conn.DeleteConfigurationProfileWithContext(ctx, &appconfig.DeleteConfigurationProfileInput{ ApplicationId: aws.String(appID), ConfigurationProfileId: aws.String(confProfID), - } - - _, err = conn.DeleteConfigurationProfileWithContext(ctx, input) + }) if tfawserr.ErrCodeEquals(err, appconfig.ErrCodeResourceNotFoundException) { return diags diff --git a/internal/service/appconfig/deployment_strategy.go b/internal/service/appconfig/deployment_strategy.go index b481d78c3c9b..bf6e354e1052 100644 --- a/internal/service/appconfig/deployment_strategy.go +++ b/internal/service/appconfig/deployment_strategy.go @@ -204,11 +204,10 @@ func resourceDeploymentStrategyDelete(ctx context.Context, d *schema.ResourceDat var diags diag.Diagnostics conn := meta.(*conns.AWSClient).AppConfigConn(ctx) - input := &appconfig.DeleteDeploymentStrategyInput{ + log.Printf("[INFO] Deleting AppConfig Deployment Strategy: %s", d.Id()) + _, err := conn.DeleteDeploymentStrategyWithContext(ctx, &appconfig.DeleteDeploymentStrategyInput{ DeploymentStrategyId: aws.String(d.Id()), - } - - _, err := conn.DeleteDeploymentStrategyWithContext(ctx, input) + }) if tfawserr.ErrCodeEquals(err, appconfig.ErrCodeResourceNotFoundException) { return diags diff --git a/internal/service/appconfig/environment_test.go b/internal/service/appconfig/environment_test.go index a5fb55f9347d..fe9c27e4b738 100644 --- a/internal/service/appconfig/environment_test.go +++ b/internal/service/appconfig/environment_test.go @@ -305,6 +305,35 @@ func TestAccAppConfigEnvironment_tags(t *testing.T) { }) } +func TestAccAppConfigEnvironment_tagsWithNullValue(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_appconfig_environment.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, appconfig.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckEnvironmentDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccEnvironmentConfig_tagsWithNullValue(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckEnvironmentExists(ctx, resourceName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + resource.TestCheckNoResourceAttr(resourceName, "tags.key2"), + ), + // ~ tags = { + // ~ "key2" = "" -> null + // # (1 unchanged element hidden) + // } + ExpectNonEmptyPlan: true, + }, + }, + }) +} + func TestAccAppConfigEnvironment_frameworkMigration_basic(t *testing.T) { ctx := acctest.Context(t) rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -440,32 +469,26 @@ func testAccCheckEnvironmentExists(ctx context.Context, resourceName string) res } func testAccEnvironmentConfig_basic(rName string) string { - return acctest.ConfigCompose( - testAccApplicationConfig_name(rName), - fmt.Sprintf(` + return acctest.ConfigCompose(testAccApplicationConfig_name(rName), fmt.Sprintf(` resource "aws_appconfig_environment" "test" { - name = %q + name = %[1]q application_id = aws_appconfig_application.test.id } `, rName)) } func testAccEnvironmentConfig_description(rName, description string) string { - return acctest.ConfigCompose( - testAccApplicationConfig_name(rName), - fmt.Sprintf(` + return acctest.ConfigCompose(testAccApplicationConfig_name(rName), fmt.Sprintf(` resource "aws_appconfig_environment" "test" { - name = %q - description = %q + name = %[1]q + description = %[2]q application_id = aws_appconfig_application.test.id } `, rName, description)) } func testAccEnvironmentConfig_monitors(rName string, count int) string { - return acctest.ConfigCompose( - testAccApplicationConfig_name(rName), - fmt.Sprintf(` + return acctest.ConfigCompose(testAccApplicationConfig_name(rName), fmt.Sprintf(` data "aws_partition" "current" {} resource "aws_iam_role" "test" { @@ -541,9 +564,7 @@ resource "aws_appconfig_environment" "test" { } func testAccEnvironmentConfig_multiple(rName string) string { - return acctest.ConfigCompose( - testAccApplicationConfig_name(rName), - fmt.Sprintf(` + return acctest.ConfigCompose(testAccApplicationConfig_name(rName), fmt.Sprintf(` resource "aws_appconfig_environment" "test" { name = %[1]q application_id = aws_appconfig_application.test.id @@ -557,9 +578,7 @@ resource "aws_appconfig_environment" "test2" { } func testAccEnvironmentConfig_tags1(rName, tagKey1, tagValue1 string) string { - return acctest.ConfigCompose( - testAccApplicationConfig_name(rName), - fmt.Sprintf(` + return acctest.ConfigCompose(testAccApplicationConfig_name(rName), fmt.Sprintf(` resource "aws_appconfig_environment" "test" { name = %[1]q application_id = aws_appconfig_application.test.id @@ -572,9 +591,7 @@ resource "aws_appconfig_environment" "test" { } func testAccEnvironmentConfig_tags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { - return acctest.ConfigCompose( - testAccApplicationConfig_name(rName), - fmt.Sprintf(` + return acctest.ConfigCompose(testAccApplicationConfig_name(rName), fmt.Sprintf(` resource "aws_appconfig_environment" "test" { name = %[1]q application_id = aws_appconfig_application.test.id @@ -586,3 +603,17 @@ resource "aws_appconfig_environment" "test" { } `, rName, tagKey1, tagValue1, tagKey2, tagValue2)) } + +func testAccEnvironmentConfig_tagsWithNullValue(rName string) string { + return acctest.ConfigCompose(testAccApplicationConfig_name(rName), fmt.Sprintf(` +resource "aws_appconfig_environment" "test" { + name = %[1]q + application_id = aws_appconfig_application.test.id + + tags = { + key1 = "value1" + key2 = null + } +} +`, rName)) +} diff --git a/internal/service/appconfig/extension_association.go b/internal/service/appconfig/extension_association.go index b2359c6da0b4..6e13c954bd3e 100644 --- a/internal/service/appconfig/extension_association.go +++ b/internal/service/appconfig/extension_association.go @@ -6,6 +6,7 @@ package appconfig import ( "context" "errors" + "log" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/appconfig" @@ -144,6 +145,7 @@ func resourceExtensionAssociationUpdate(ctx context.Context, d *schema.ResourceD func resourceExtensionAssociationDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*conns.AWSClient).AppConfigConn(ctx) + log.Printf("[INFO] Deleting AppConfig Hosted Extension Association: %s", d.Id()) _, err := conn.DeleteExtensionAssociationWithContext(ctx, &appconfig.DeleteExtensionAssociationInput{ ExtensionAssociationId: aws.String(d.Id()), }) diff --git a/internal/service/appconfig/hosted_configuration_version.go b/internal/service/appconfig/hosted_configuration_version.go index a7848c030d24..b3a38d1c248a 100644 --- a/internal/service/appconfig/hosted_configuration_version.go +++ b/internal/service/appconfig/hosted_configuration_version.go @@ -161,18 +161,16 @@ func resourceHostedConfigurationVersionDelete(ctx context.Context, d *schema.Res conn := meta.(*conns.AWSClient).AppConfigConn(ctx) appID, confProfID, versionNumber, err := HostedConfigurationVersionParseID(d.Id()) - if err != nil { - return sdkdiag.AppendErrorf(diags, "deleting Appconfig Hosted Configuration Version (%s): %s", d.Id(), err) + return sdkdiag.AppendFromErr(diags, err) } - input := &appconfig.DeleteHostedConfigurationVersionInput{ + log.Printf("[INFO] Deleting AppConfig Hosted Configuration Version: %s", d.Id()) + _, err = conn.DeleteHostedConfigurationVersionWithContext(ctx, &appconfig.DeleteHostedConfigurationVersionInput{ ApplicationId: aws.String(appID), ConfigurationProfileId: aws.String(confProfID), VersionNumber: aws.Int64(int64(versionNumber)), - } - - _, err = conn.DeleteHostedConfigurationVersionWithContext(ctx, input) + }) if tfawserr.ErrCodeEquals(err, appconfig.ErrCodeResourceNotFoundException) { return diags diff --git a/internal/service/appconfig/sweep.go b/internal/service/appconfig/sweep.go index b048354047ad..29c2db845ee1 100644 --- a/internal/service/appconfig/sweep.go +++ b/internal/service/appconfig/sweep.go @@ -24,6 +24,7 @@ func RegisterSweepers() { Dependencies: []string{ "aws_appconfig_configuration_profile", "aws_appconfig_environment", + "aws_appconfig_extension_association", }, }) @@ -31,6 +32,7 @@ func RegisterSweepers() { Name: "aws_appconfig_configuration_profile", F: sweepConfigurationProfiles, Dependencies: []string{ + "aws_appconfig_extension_association", "aws_appconfig_hosted_configuration_version", }, }) @@ -43,44 +45,41 @@ func RegisterSweepers() { resource.AddTestSweepers("aws_appconfig_environment", &resource.Sweeper{ Name: "aws_appconfig_environment", F: sweepEnvironments, + Dependencies: []string{ + "aws_appconfig_extension_association", + }, }) resource.AddTestSweepers("aws_appconfig_hosted_configuration_version", &resource.Sweeper{ Name: "aws_appconfig_hosted_configuration_version", F: sweepHostedConfigurationVersions, }) + + resource.AddTestSweepers("aws_appconfig_extension_association", &resource.Sweeper{ + Name: "aws_appconfig_extension_association", + F: sweepExtensionAssociations, + }) } func sweepApplications(region string) error { ctx := sweep.Context(region) client, err := sweep.SharedRegionalSweepClient(ctx, region) - if err != nil { return fmt.Errorf("error getting client: %w", err) } - conn := client.AppConfigConn(ctx) - sweepResources := make([]sweep.Sweepable, 0) - var errs *multierror.Error - input := &appconfig.ListApplicationsInput{} + sweepResources := make([]sweep.Sweepable, 0) err = conn.ListApplicationsPagesWithContext(ctx, input, func(page *appconfig.ListApplicationsOutput, lastPage bool) bool { if page == nil { return !lastPage } - for _, item := range page.Items { - if item == nil { - continue - } - - id := aws.StringValue(item.Id) - - log.Printf("[INFO] Deleting AppConfig Application (%s)", id) + for _, v := range page.Items { r := ResourceApplication() d := r.Data(nil) - d.SetId(id) + d.SetId(aws.StringValue(v.Id)) sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) } @@ -88,68 +87,51 @@ func sweepApplications(region string) error { return !lastPage }) - if err != nil { - errs = multierror.Append(errs, fmt.Errorf("error listing AppConfig Applications: %w", err)) + if awsv1.SkipSweepError(err) { + log.Printf("[WARN] Skipping AppConfig Application sweep for %s: %s", region, err) + return nil } - if err = sweep.SweepOrchestrator(ctx, sweepResources); err != nil { - errs = multierror.Append(errs, fmt.Errorf("error sweeping AppConfig Applications for %s: %w", region, err)) + if err != nil { + return fmt.Errorf("error listing AppConfig Applications (%s): %w", region, err) } - if awsv1.SkipSweepError(errs.ErrorOrNil()) { - log.Printf("[WARN] Skipping AppConfig Applications sweep for %s: %s", region, errs) - return nil + err = sweep.SweepOrchestrator(ctx, sweepResources) + + if err != nil { + return fmt.Errorf("error sweeping AppConfig Applications (%s): %w", region, err) } - return errs.ErrorOrNil() + return nil } func sweepConfigurationProfiles(region string) error { ctx := sweep.Context(region) client, err := sweep.SharedRegionalSweepClient(ctx, region) - if err != nil { return fmt.Errorf("error getting client: %w", err) } - conn := client.AppConfigConn(ctx) - sweepResources := make([]sweep.Sweepable, 0) - var errs *multierror.Error - input := &appconfig.ListApplicationsInput{} + sweepResources := make([]sweep.Sweepable, 0) + var sweeperErrs *multierror.Error err = conn.ListApplicationsPagesWithContext(ctx, input, func(page *appconfig.ListApplicationsOutput, lastPage bool) bool { if page == nil { return !lastPage } - for _, item := range page.Items { - if item == nil { - continue + for _, v := range page.Items { + appID := aws.StringValue(v.Id) + input := &appconfig.ListConfigurationProfilesInput{ + ApplicationId: aws.String(appID), } - appId := aws.StringValue(item.Id) - - profilesInput := &appconfig.ListConfigurationProfilesInput{ - ApplicationId: item.Id, - } - - err := conn.ListConfigurationProfilesPagesWithContext(ctx, profilesInput, func(page *appconfig.ListConfigurationProfilesOutput, lastPage bool) bool { - if page == nil { - return !lastPage - } - - for _, item := range page.Items { - if item == nil { - continue - } - - id := fmt.Sprintf("%s:%s", aws.StringValue(item.Id), appId) - - log.Printf("[INFO] Deleting AppConfig Configuration Profile (%s)", id) + err := conn.ListConfigurationProfilesPagesWithContext(ctx, input, func(page *appconfig.ListConfigurationProfilesOutput, lastPage bool) bool { + for _, v := range page.Items { r := ResourceConfigurationProfile() d := r.Data(nil) - d.SetId(id) + d.SetId(fmt.Sprintf("%s:%s", aws.StringValue(v.Id), appID)) sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) } @@ -157,55 +139,53 @@ func sweepConfigurationProfiles(region string) error { return !lastPage }) + if awsv1.SkipSweepError(err) { + continue + } + if err != nil { - errs = multierror.Append(errs, fmt.Errorf("error listing AppConfig Configuration Profiles for Application (%s): %w", appId, err)) + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing AppConfig Configuration Profiles (%s): %w", region, err)) } } return !lastPage }) - if err != nil { - errs = multierror.Append(errs, fmt.Errorf("error listing AppConfig Applications: %w", err)) + if awsv1.SkipSweepError(err) { + log.Printf("[WARN] Skipping AppConfig Configuration Profile sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() } - if err = sweep.SweepOrchestrator(ctx, sweepResources); err != nil { - errs = multierror.Append(errs, fmt.Errorf("error sweeping AppConfig Configuration Profiles for %s: %w", region, err)) + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing AppConfig Applications (%s): %w", region, err)) } - if awsv1.SkipSweepError(errs.ErrorOrNil()) { - log.Printf("[WARN] Skipping AppConfig Configuration Profiles sweep for %s: %s", region, errs) - return nil + err = sweep.SweepOrchestrator(ctx, sweepResources) + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error sweeping AppConfig Configuration Profiles (%s): %w", region, err)) } - return errs.ErrorOrNil() + return sweeperErrs.ErrorOrNil() } func sweepDeploymentStrategies(region string) error { ctx := sweep.Context(region) client, err := sweep.SharedRegionalSweepClient(ctx, region) - if err != nil { return fmt.Errorf("error getting client: %w", err) } - conn := client.AppConfigConn(ctx) - sweepResources := make([]sweep.Sweepable, 0) - var errs *multierror.Error - input := &appconfig.ListDeploymentStrategiesInput{} + sweepResources := make([]sweep.Sweepable, 0) err = conn.ListDeploymentStrategiesPagesWithContext(ctx, input, func(page *appconfig.ListDeploymentStrategiesOutput, lastPage bool) bool { if page == nil { return !lastPage } - for _, item := range page.Items { - if item == nil { - continue - } - - id := aws.StringValue(item.Id) + for _, v := range page.Items { + id := aws.StringValue(v.Id) // Deleting AppConfig Predefined Strategies is not supported; returns BadRequestException if regexache.MustCompile(`^AppConfig\.[0-9A-Za-z]{9,40}$`).MatchString(id) { @@ -213,7 +193,6 @@ func sweepDeploymentStrategies(region string) error { continue } - log.Printf("[INFO] Deleting AppConfig Deployment Strategy (%s)", id) r := ResourceDeploymentStrategy() d := r.Data(nil) d.SetId(id) @@ -224,158 +203,134 @@ func sweepDeploymentStrategies(region string) error { return !lastPage }) - if err != nil { - errs = multierror.Append(errs, fmt.Errorf("error listing AppConfig Deployment Strategies: %w", err)) + if awsv1.SkipSweepError(err) { + log.Printf("[WARN] Skipping AppConfig Deployment Strategy sweep for %s: %s", region, err) + return nil } - if err = sweep.SweepOrchestrator(ctx, sweepResources); err != nil { - errs = multierror.Append(errs, fmt.Errorf("error sweeping AppConfig Deployment Strategies for %s: %w", region, err)) + if err != nil { + return fmt.Errorf("error listing AppConfig Deployment Strategies (%s): %w", region, err) } - if awsv1.SkipSweepError(errs.ErrorOrNil()) { - log.Printf("[WARN] Skipping AppConfig Deployment Strategies sweep for %s: %s", region, errs) - return nil + err = sweep.SweepOrchestrator(ctx, sweepResources) + + if err != nil { + return fmt.Errorf("error sweeping AppConfig Deployment Strategies (%s): %w", region, err) } - return errs.ErrorOrNil() + return nil } func sweepEnvironments(region string) error { ctx := sweep.Context(region) client, err := sweep.SharedRegionalSweepClient(ctx, region) - if err != nil { return fmt.Errorf("error getting client: %w", err) } - conn := client.AppConfigConn(ctx) - sweepResources := make([]sweep.Sweepable, 0) - var errs *multierror.Error - input := &appconfig.ListApplicationsInput{} + sweepResources := make([]sweep.Sweepable, 0) + var sweeperErrs *multierror.Error err = conn.ListApplicationsPagesWithContext(ctx, input, func(page *appconfig.ListApplicationsOutput, lastPage bool) bool { if page == nil { return !lastPage } - for _, item := range page.Items { - if item == nil { - continue + for _, v := range page.Items { + appID := aws.StringValue(v.Id) + input := &appconfig.ListEnvironmentsInput{ + ApplicationId: aws.String(appID), } - appId := aws.StringValue(item.Id) - - envInput := &appconfig.ListEnvironmentsInput{ - ApplicationId: item.Id, - } - - err := conn.ListEnvironmentsPagesWithContext(ctx, envInput, func(page *appconfig.ListEnvironmentsOutput, lastPage bool) bool { + err := conn.ListEnvironmentsPagesWithContext(ctx, input, func(page *appconfig.ListEnvironmentsOutput, lastPage bool) bool { if page == nil { return !lastPage } - for _, item := range page.Items { - if item == nil { - continue - } - + for _, v := range page.Items { sweepResources = append(sweepResources, framework.NewSweepResource(newResourceEnvironment, client, - framework.NewAttribute("application_id", aws.StringValue(item.ApplicationId)), - framework.NewAttribute("environment_id", aws.StringValue(item.Id)), + framework.NewAttribute("application_id", aws.StringValue(v.ApplicationId)), + framework.NewAttribute("environment_id", aws.StringValue(v.Id)), )) } return !lastPage }) + if awsv1.SkipSweepError(err) { + continue + } + if err != nil { - errs = multierror.Append(errs, fmt.Errorf("error listing AppConfig Environments for Application (%s): %w", appId, err)) + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing AppConfig Environments (%s): %w", region, err)) } } return !lastPage }) - if err != nil { - errs = multierror.Append(errs, fmt.Errorf("error listing AppConfig Applications: %w", err)) + if awsv1.SkipSweepError(err) { + log.Printf("[WARN] Skipping AppConfig Environment sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() } - if err = sweep.SweepOrchestrator(ctx, sweepResources); err != nil { - errs = multierror.Append(errs, fmt.Errorf("error sweeping AppConfig Environments for %s: %w", region, err)) + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing AppConfig Applications (%s): %w", region, err)) } - if awsv1.SkipSweepError(errs.ErrorOrNil()) { - log.Printf("[WARN] Skipping AppConfig Environments sweep for %s: %s", region, errs) - return nil + err = sweep.SweepOrchestrator(ctx, sweepResources) + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error sweeping AppConfig Environments (%s): %w", region, err)) } - return errs.ErrorOrNil() + return sweeperErrs.ErrorOrNil() } func sweepHostedConfigurationVersions(region string) error { ctx := sweep.Context(region) client, err := sweep.SharedRegionalSweepClient(ctx, region) - if err != nil { return fmt.Errorf("error getting client: %w", err) } - conn := client.AppConfigConn(ctx) - sweepResources := make([]sweep.Sweepable, 0) - var errs *multierror.Error - input := &appconfig.ListApplicationsInput{} + sweepResources := make([]sweep.Sweepable, 0) + var sweeperErrs *multierror.Error err = conn.ListApplicationsPagesWithContext(ctx, input, func(page *appconfig.ListApplicationsOutput, lastPage bool) bool { if page == nil { return !lastPage } - for _, item := range page.Items { - if item == nil { - continue - } - - appId := aws.StringValue(item.Id) - - profilesInput := &appconfig.ListConfigurationProfilesInput{ - ApplicationId: item.Id, + for _, v := range page.Items { + appID := aws.StringValue(v.Id) + input := &appconfig.ListConfigurationProfilesInput{ + ApplicationId: aws.String(appID), } - err := conn.ListConfigurationProfilesPagesWithContext(ctx, profilesInput, func(page *appconfig.ListConfigurationProfilesOutput, lastPage bool) bool { + err := conn.ListConfigurationProfilesPagesWithContext(ctx, input, func(page *appconfig.ListConfigurationProfilesOutput, lastPage bool) bool { if page == nil { return !lastPage } - for _, item := range page.Items { - if item == nil { - continue - } - - profId := aws.StringValue(item.Id) - - versionInput := &appconfig.ListHostedConfigurationVersionsInput{ - ApplicationId: aws.String(appId), - ConfigurationProfileId: aws.String(profId), + for _, v := range page.Items { + profileID := aws.StringValue(v.Id) + input := &appconfig.ListHostedConfigurationVersionsInput{ + ApplicationId: aws.String(appID), + ConfigurationProfileId: aws.String(profileID), } - err := conn.ListHostedConfigurationVersionsPagesWithContext(ctx, versionInput, func(page *appconfig.ListHostedConfigurationVersionsOutput, lastPage bool) bool { + err := conn.ListHostedConfigurationVersionsPagesWithContext(ctx, input, func(page *appconfig.ListHostedConfigurationVersionsOutput, lastPage bool) bool { if page == nil { return !lastPage } - for _, item := range page.Items { - if item == nil { - continue - } - - id := fmt.Sprintf("%s/%s/%d", appId, profId, aws.Int64Value(item.VersionNumber)) - - log.Printf("[INFO] Deleting AppConfig Hosted Configuration Version (%s)", id) + for _, v := range page.Items { r := ResourceHostedConfigurationVersion() d := r.Data(nil) - d.SetId(id) + d.SetId(fmt.Sprintf("%s/%s/%d", appID, profileID, aws.Int64Value(v.VersionNumber))) sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) } @@ -383,34 +338,88 @@ func sweepHostedConfigurationVersions(region string) error { return !lastPage }) + if awsv1.SkipSweepError(err) { + continue + } + if err != nil { - errs = multierror.Append(errs, fmt.Errorf("error listing AppConfig Hosted Configuration Versions for Application (%s) and Configuration Profile (%s): %w", appId, profId, err)) + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing AppConfig Hosted Configuration Versions (%s): %w", region, err)) } } return !lastPage }) + if awsv1.SkipSweepError(err) { + continue + } + if err != nil { - errs = multierror.Append(errs, fmt.Errorf("error listing AppConfig Configuration Profiles for Application (%s): %w", appId, err)) + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing AppConfig Configuration Profiles (%s): %w", region, err)) } } return !lastPage }) + if awsv1.SkipSweepError(err) { + log.Printf("[WARN] Skipping AppConfig Hosted Configuration Version sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() + } + if err != nil { - errs = multierror.Append(errs, fmt.Errorf("error listing AppConfig Applications: %w", err)) + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error listing AppConfig Applications (%s): %w", region, err)) } - if err = sweep.SweepOrchestrator(ctx, sweepResources); err != nil { - errs = multierror.Append(errs, fmt.Errorf("error sweeping AppConfig Hosted Configuration Versions for %s: %w", region, err)) + err = sweep.SweepOrchestrator(ctx, sweepResources) + + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error sweeping AppConfig Hosted Configuration Versions (%s): %w", region, err)) } - if awsv1.SkipSweepError(errs.ErrorOrNil()) { - log.Printf("[WARN] Skipping AppConfig Hosted Configuration Versions sweep for %s: %s", region, errs) + return sweeperErrs.ErrorOrNil() +} + +func sweepExtensionAssociations(region string) error { + ctx := sweep.Context(region) + client, err := sweep.SharedRegionalSweepClient(ctx, region) + if err != nil { + return fmt.Errorf("error getting client: %w", err) + } + conn := client.AppConfigConn(ctx) + input := &appconfig.ListExtensionAssociationsInput{} + sweepResources := make([]sweep.Sweepable, 0) + + err = conn.ListExtensionAssociationsPagesWithContext(ctx, input, func(page *appconfig.ListExtensionAssociationsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.Items { + r := ResourceExtensionAssociation() + d := r.Data(nil) + d.SetId(aws.StringValue(v.Id)) + + sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) + } + + return !lastPage + }) + + if awsv1.SkipSweepError(err) { + log.Printf("[WARN] Skipping AppConfig Extension Association sweep for %s: %s", region, err) return nil } - return errs.ErrorOrNil() + if err != nil { + return fmt.Errorf("error listing AppConfig Extension Associations (%s): %w", region, err) + } + + err = sweep.SweepOrchestrator(ctx, sweepResources) + + if err != nil { + return fmt.Errorf("error sweeping AppConfig Extension Associations (%s): %w", region, err) + } + + return nil } diff --git a/internal/tags/key_value_tags.go b/internal/tags/key_value_tags.go index f07839f7fe3b..392d5fa6e8e0 100644 --- a/internal/tags/key_value_tags.go +++ b/internal/tags/key_value_tags.go @@ -644,7 +644,7 @@ func New(ctx context.Context, i interface{}) KeyValueTags { return kvtm case types.Map: - return New(ctx, flex.ExpandFrameworkStringValueMap(ctx, value)) + return New(ctx, flex.ExpandFrameworkStringMap(ctx, value)) default: return make(KeyValueTags) }