Skip to content

Commit

Permalink
r/aws_cloudwatch_log_delivery_destination: 'destination_resource_arn'…
Browse files Browse the repository at this point in the history
… is ForceNew if the type changes.
  • Loading branch information
ewbankkit committed Dec 31, 2024
1 parent b7da267 commit ec90ee3
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 3 deletions.
23 changes: 23 additions & 0 deletions internal/service/logs/delivery_destination.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/aws/arn"
"github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs"
awstypes "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs/types"
"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
Expand Down Expand Up @@ -35,6 +36,7 @@ import (
// @Testing(tagsTest=false)
func newDeliveryDestinationResource(context.Context) (resource.ResourceWithConfigure, error) {
r := &deliveryDestinationResource{}

return r, nil
}

Expand Down Expand Up @@ -86,6 +88,9 @@ func (r *deliveryDestinationResource) Schema(ctx context.Context, request resour
"destination_resource_arn": schema.StringAttribute{
CustomType: fwtypes.ARNType,
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplaceIf(requiresReplaceIfARNServiceChanges, "", ""),
},
},
},
},
Expand Down Expand Up @@ -265,6 +270,24 @@ func findDeliveryDestination(ctx context.Context, conn *cloudwatchlogs.Client, i
return output.DeliveryDestination, nil
}

// requiresReplaceIfARNServiceChanges forces a new resource if and ARN attribute's service changes.
// If the new value is unknown, force a new resource.
func requiresReplaceIfARNServiceChanges(ctx context.Context, request planmodifier.StringRequest, response *stringplanmodifier.RequiresReplaceIfFuncResponse) {
requiresReplace := false

if request.PlanValue.IsUnknown() {
requiresReplace = true
} else {
new, _ := arn.Parse(fwflex.StringValueFromFramework(ctx, request.PlanValue))
old, _ := arn.Parse(fwflex.StringValueFromFramework(ctx, request.StateValue))
if new.Service != old.Service {
requiresReplace = true
}
}

response.RequiresReplace = requiresReplace
}

type deliveryDestinationResourceModel struct {
ARN types.String `tfsdk:"arn"`
DeliveryDestinationConfiguration fwtypes.ListNestedObjectValueOf[deliveryDestinationConfigurationModel] `tfsdk:"delivery_destination_configuration"`
Expand Down
112 changes: 109 additions & 3 deletions internal/service/logs/delivery_destination_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ func TestAccLogsDeliveryDestination_outputFormat(t *testing.T) {
})
}

func TestAccLogsDeliveryDestination_updateDeliveryDestinationConfiguration(t *testing.T) {
func TestAccLogsDeliveryDestination_updateDeliveryDestinationConfigurationSameType(t *testing.T) {
ctx := acctest.Context(t)
var v awstypes.DeliveryDestination
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
Expand All @@ -234,7 +234,7 @@ func TestAccLogsDeliveryDestination_updateDeliveryDestinationConfiguration(t *te
CheckDestroy: testAccCheckDeliveryDestinationDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccLogDeliveryDestinationConfig_basic(rName),
Config: testAccLogDeliveryDestinationConfig_deliveryDestinationConfigurationCWL1(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckDeliveryDestinationExists(ctx, resourceName, &v),
),
Expand All @@ -255,7 +255,7 @@ func TestAccLogsDeliveryDestination_updateDeliveryDestinationConfiguration(t *te
ImportStateVerifyIdentifierAttribute: names.AttrName,
},
{
Config: testAccLogDeliveryDestinationConfig_outputFormat(rName, "w3c"),
Config: testAccLogDeliveryDestinationConfig_deliveryDestinationConfigurationCWL2(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckDeliveryDestinationExists(ctx, resourceName, &v),
),
Expand All @@ -264,6 +264,59 @@ func TestAccLogsDeliveryDestination_updateDeliveryDestinationConfiguration(t *te
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate),
},
},
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("delivery_destination_type"), knownvalue.StringExact("CWL")),
},
},
},
})
}

func TestAccLogsDeliveryDestination_updateDeliveryDestinationConfigurationDifferentType(t *testing.T) {
ctx := acctest.Context(t)
var v awstypes.DeliveryDestination
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_cloudwatch_log_delivery_destination.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, names.LogsServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckDeliveryDestinationDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccLogDeliveryDestinationConfig_deliveryDestinationConfigurationCWL1(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckDeliveryDestinationExists(ctx, resourceName, &v),
),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate),
},
},
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("delivery_destination_type"), knownvalue.StringExact("CWL")),
},
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateIdFunc: testAccDeliveryDestinationImportStateIDFunc(resourceName),
ImportStateVerifyIdentifierAttribute: names.AttrName,
},
{
Config: testAccLogDeliveryDestinationConfig_deliveryDestinationConfigurationS3(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckDeliveryDestinationExists(ctx, resourceName, &v),
),
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionDestroyBeforeCreate),
},
},
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New("delivery_destination_type"), knownvalue.StringExact("S3")),
},
Expand Down Expand Up @@ -404,3 +457,56 @@ resource "aws_cloudwatch_log_delivery_destination" "test" {
}
`, rName, outputFormat)
}

func testAccLogDeliveryDestinationConfig_deliveryDestinationConfigurationBase(rName string) string {
return fmt.Sprintf(`
resource "aws_cloudwatch_log_group" "test1" {
name = "%[1]s-1"
}
resource "aws_cloudwatch_log_group" "test2" {
name = "%[1]s-2"
}
resource "aws_s3_bucket" "test" {
bucket = %[1]q
force_destroy = true
}
`, rName)
}

func testAccLogDeliveryDestinationConfig_deliveryDestinationConfigurationCWL1(rName string) string {
return acctest.ConfigCompose(testAccLogDeliveryDestinationConfig_deliveryDestinationConfigurationBase(rName), fmt.Sprintf(`
resource "aws_cloudwatch_log_delivery_destination" "test" {
name = %[1]q
delivery_destination_configuration {
destination_resource_arn = aws_cloudwatch_log_group.test1.arn
}
}
`, rName))
}

func testAccLogDeliveryDestinationConfig_deliveryDestinationConfigurationCWL2(rName string) string {
return acctest.ConfigCompose(testAccLogDeliveryDestinationConfig_deliveryDestinationConfigurationBase(rName), fmt.Sprintf(`
resource "aws_cloudwatch_log_delivery_destination" "test" {
name = %[1]q
delivery_destination_configuration {
destination_resource_arn = aws_cloudwatch_log_group.test2.arn
}
}
`, rName))
}

func testAccLogDeliveryDestinationConfig_deliveryDestinationConfigurationS3(rName string) string {
return acctest.ConfigCompose(testAccLogDeliveryDestinationConfig_deliveryDestinationConfigurationBase(rName), fmt.Sprintf(`
resource "aws_cloudwatch_log_delivery_destination" "test" {
name = %[1]q
delivery_destination_configuration {
destination_resource_arn = aws_s3_bucket.test.arn
}
}
`, rName))
}

0 comments on commit ec90ee3

Please sign in to comment.