Skip to content

Commit 3b30f26

Browse files
authored
Add parameterized resource identity to aws_cloudwatch_event_target (#43984)
Adds resource identity support. ```console % make testacc PKG=events TESTS=TestAccEventsTarget_ make: Verifying source code with gofmt... ==> Checking that code complies with gofmt requirements... TF_ACC=1 go1.24.6 test ./internal/service/events/... -v -count 1 -parallel 20 -run='TestAccEventsTarget_' -timeout 360m -vet=off 2025/08/21 09:33:15 Creating Terraform AWS Provider (SDKv2-style)... 2025/08/21 09:33:15 Initializing Terraform AWS Provider (SDKv2-style)... --- PASS: TestAccEventsTarget_disappears (26.34s) === CONT TestAccEventsTarget_Input_transformer --- PASS: TestAccEventsTarget_ssmDocument (31.95s) === CONT TestAccEventsTarget_sqs --- PASS: TestAccEventsTarget_http (32.32s) === CONT TestAccEventsTarget_Identity_ExistingResource --- PASS: TestAccEventsTarget_sageMakerPipeline (32.90s) === CONT TestAccEventsTarget_basic --- PASS: TestAccEventsTarget_appsync (33.63s) === CONT TestAccEventsTarget_full --- PASS: TestAccEventsTarget_Identity_Basic (57.14s) === CONT TestAccEventsTarget_Identity_RegionOverride --- PASS: TestAccEventsTarget_ecsFull (57.89s) === CONT TestAccEventsTarget_eventBusARN --- PASS: TestAccEventsTarget_http_params (62.84s) === CONT TestAccEventsTarget_generatedTargetID --- PASS: TestAccEventsTarget_inputTransformerJSONString (64.51s) === CONT TestAccEventsTarget_eventBusName --- PASS: TestAccEventsTarget_ecsCapacityProvider (76.12s) --- PASS: TestAccEventsTarget_kinesis (80.11s) --- PASS: TestAccEventsTarget_RetryPolicy_deadLetter (83.18s) --- PASS: TestAccEventsTarget_Input_transformer (60.93s) --- PASS: TestAccEventsTarget_eventBusARN (48.03s) --- PASS: TestAccEventsTarget_sqs (75.19s) --- PASS: TestAccEventsTarget_generatedTargetID (48.65s) --- PASS: TestAccEventsTarget_full (78.15s) --- PASS: TestAccEventsTarget_eventBusName (47.61s) --- PASS: TestAccEventsTarget_basic (82.47s) --- PASS: TestAccEventsTarget_Identity_RegionOverride (62.13s) --- PASS: TestAccEventsTarget_Identity_ExistingResource (88.45s) --- PASS: TestAccEventsTarget_ecsWithoutLaunchType (121.69s) --- PASS: TestAccEventsTarget_ecsWithBlankLaunchType (124.09s) --- PASS: TestAccEventsTarget_batch (178.80s) --- PASS: TestAccEventsTarget_redshift (284.89s) --- PASS: TestAccEventsTarget_ecsNoPropagateTags (339.74s) --- PASS: TestAccEventsTarget_ecs (350.33s) --- PASS: TestAccEventsTarget_ecsWithBlankTaskCount (371.21s) === NAME TestAccEventsTarget_ecsPlacementStrategy target_test.go:899: Error running post-test destroy, there may be dangling resources: exit status 1 Error: waiting for ECS Capacity Provider (arn:aws:ecs:us-west-2:727561393803:capacity-provider/tf-acc-test-6131568012180198971) delete: timeout while waiting for resource to be gone (last state: 'ACTIVE', timeout: 20m0s) --- FAIL: TestAccEventsTarget_ecsPlacementStrategy (1272.28s) FAIL FAIL github.com/hashicorp/terraform-provider-aws/internal/service/events 1279.061s ``` Test failure is during post-test cleanup and unrelated to these changes.
1 parent b3eb84d commit 3b30f26

File tree

8 files changed

+474
-63
lines changed

8 files changed

+474
-63
lines changed

.changelog/43984.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
resource/aws_cloudwatch_event_target: Add resource identity support
3+
```

internal/service/events/service_package_gen.go

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/service/events/target.go

Lines changed: 80 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -29,35 +29,26 @@ import (
2929
tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices"
3030
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
3131
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
32+
inttypes "github.com/hashicorp/terraform-provider-aws/internal/types"
3233
"github.com/hashicorp/terraform-provider-aws/internal/verify"
3334
"github.com/hashicorp/terraform-provider-aws/names"
3435
)
3536

3637
// @SDKResource("aws_cloudwatch_event_target", name="Target")
38+
// @IdentityAttribute("event_bus_name")
39+
// @IdentityAttribute("rule")
40+
// @IdentityAttribute("target_id")
41+
// @ImportIDHandler("targetImportID")
42+
// @Testing(preIdentityVersion="v6.9.0")
43+
// @Testing(existsType="github.com/aws/aws-sdk-go-v2/service/eventbridge/types;types.Target")
44+
// @Testing(importStateIdFunc="testAccTargetImportStateIdFunc")
3745
func resourceTarget() *schema.Resource {
3846
return &schema.Resource{
3947
CreateWithoutTimeout: resourceTargetCreate,
4048
ReadWithoutTimeout: resourceTargetRead,
4149
UpdateWithoutTimeout: resourceTargetUpdate,
4250
DeleteWithoutTimeout: resourceTargetDelete,
4351

44-
Importer: &schema.ResourceImporter{
45-
StateContext: func(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) {
46-
busName, ruleName, targetID, err := targetParseImportID(d.Id())
47-
if err != nil {
48-
return []*schema.ResourceData{}, err
49-
}
50-
51-
id := targetCreateResourceID(busName, ruleName, targetID)
52-
d.SetId(id)
53-
d.Set("target_id", targetID)
54-
d.Set(names.AttrRule, ruleName)
55-
d.Set("event_bus_name", busName)
56-
57-
return []*schema.ResourceData{d}, nil
58-
},
59-
},
60-
6152
SchemaVersion: 1,
6253
StateUpgraders: []schema.StateUpgrader{
6354
{
@@ -755,52 +746,6 @@ func findTargets(ctx context.Context, conn *eventbridge.Client, input *eventbrid
755746
return output, nil
756747
}
757748

758-
// Terraform resource IDs for Targets are not parseable as the separator used ("-") is also a valid character in both the rule name and the target ID.
759-
const (
760-
targetResourceIDSeparator = "-"
761-
targetImportIDSeparator = "/"
762-
)
763-
764-
func targetCreateResourceID(eventBusName, ruleName, targetID string) string {
765-
var parts []string
766-
767-
if eventBusName == "" || eventBusName == DefaultEventBusName {
768-
parts = []string{ruleName, targetID}
769-
} else {
770-
parts = []string{eventBusName, ruleName, targetID}
771-
}
772-
773-
id := strings.Join(parts, targetResourceIDSeparator)
774-
775-
return id
776-
}
777-
778-
func targetParseImportID(id string) (string, string, string, error) {
779-
parts := strings.Split(id, targetImportIDSeparator)
780-
781-
if len(parts) == 2 && parts[0] != "" && parts[1] != "" {
782-
return DefaultEventBusName, parts[0], parts[1], nil
783-
}
784-
if len(parts) == 3 && parts[0] != "" && parts[1] != "" && parts[2] != "" {
785-
return parts[0], parts[1], parts[2], nil
786-
}
787-
if len(parts) > 3 {
788-
iTarget := strings.LastIndex(id, targetImportIDSeparator)
789-
targetID := id[iTarget+1:]
790-
iRule := strings.LastIndex(id[:iTarget], targetImportIDSeparator)
791-
eventBusName := id[:iRule]
792-
ruleName := id[iRule+1 : iTarget]
793-
if eventBusARNPattern.MatchString(eventBusName) && ruleName != "" && targetID != "" {
794-
return eventBusName, ruleName, targetID, nil
795-
}
796-
if partnerEventBusPattern.MatchString(eventBusName) && ruleName != "" && targetID != "" {
797-
return eventBusName, ruleName, targetID, nil
798-
}
799-
}
800-
801-
return "", "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected EVENTBUSNAME%[2]sRULENAME%[2]sTARGETID or RULENAME%[2]sTARGETID", id, targetImportIDSeparator)
802-
}
803-
804749
func putTargetError(apiObject types.PutTargetsResultEntry) error {
805750
return errs.APIError(aws.ToString(apiObject.ErrorCode), aws.ToString(apiObject.ErrorMessage))
806751
}
@@ -1528,3 +1473,75 @@ func expandAppSyncParameters(tfList []any) *types.AppSyncParameters {
15281473

15291474
return apiObject
15301475
}
1476+
1477+
// Terraform resource IDs for Targets are not parseable as the separator used ("-") is also a valid character in both the rule name and the target ID.
1478+
const (
1479+
targetResourceIDSeparator = "-"
1480+
targetImportIDSeparator = "/"
1481+
)
1482+
1483+
func targetCreateResourceID(eventBusName, ruleName, targetID string) string {
1484+
var parts []string
1485+
1486+
if eventBusName == "" || eventBusName == DefaultEventBusName {
1487+
parts = []string{ruleName, targetID}
1488+
} else {
1489+
parts = []string{eventBusName, ruleName, targetID}
1490+
}
1491+
1492+
id := strings.Join(parts, targetResourceIDSeparator)
1493+
1494+
return id
1495+
}
1496+
1497+
func targetParseImportID(id string) (string, string, string, error) {
1498+
parts := strings.Split(id, targetImportIDSeparator)
1499+
1500+
if len(parts) == 2 && parts[0] != "" && parts[1] != "" {
1501+
return DefaultEventBusName, parts[0], parts[1], nil
1502+
}
1503+
if len(parts) == 3 && parts[0] != "" && parts[1] != "" && parts[2] != "" {
1504+
return parts[0], parts[1], parts[2], nil
1505+
}
1506+
if len(parts) > 3 {
1507+
iTarget := strings.LastIndex(id, targetImportIDSeparator)
1508+
targetID := id[iTarget+1:]
1509+
iRule := strings.LastIndex(id[:iTarget], targetImportIDSeparator)
1510+
eventBusName := id[:iRule]
1511+
ruleName := id[iRule+1 : iTarget]
1512+
if eventBusARNPattern.MatchString(eventBusName) && ruleName != "" && targetID != "" {
1513+
return eventBusName, ruleName, targetID, nil
1514+
}
1515+
if partnerEventBusPattern.MatchString(eventBusName) && ruleName != "" && targetID != "" {
1516+
return eventBusName, ruleName, targetID, nil
1517+
}
1518+
}
1519+
1520+
return "", "", "", fmt.Errorf("unexpected format for ID (%[1]s), expected EVENTBUSNAME%[2]sRULENAME%[2]sTARGETID or RULENAME%[2]sTARGETID", id, targetImportIDSeparator)
1521+
}
1522+
1523+
var _ inttypes.SDKv2ImportID = targetImportID{}
1524+
1525+
type targetImportID struct{}
1526+
1527+
func (targetImportID) Create(d *schema.ResourceData) string {
1528+
eventBusName := d.Get("event_bus_name").(string)
1529+
rule := d.Get(names.AttrRule).(string)
1530+
targetID := d.Get("target_id").(string)
1531+
return targetCreateResourceID(eventBusName, rule, targetID)
1532+
}
1533+
1534+
func (targetImportID) Parse(id string) (string, map[string]string, error) {
1535+
eventBusName, rule, targetID, err := targetParseImportID(id)
1536+
if err != nil {
1537+
return id, nil, err
1538+
}
1539+
1540+
results := map[string]string{
1541+
"event_bus_name": eventBusName,
1542+
names.AttrRule: rule,
1543+
"target_id": targetID,
1544+
}
1545+
1546+
return targetCreateResourceID(eventBusName, rule, targetID), results, nil
1547+
}

0 commit comments

Comments
 (0)