Configure AWS EventBridge Targets

The aws:cloudwatch/eventTarget:EventTarget resource, part of the Pulumi AWS provider, connects EventBridge rules to AWS services that process matched events. This guide focuses on four capabilities: routing to Kinesis, ECS, and API Gateway; SSM Run Command with tag-based targeting; cross-account event forwarding; and input transformation for custom payloads.

Event targets depend on EventBridge rules that define matching patterns, IAM roles with permissions for target services, and the target resources themselves. The examples are intentionally small. Combine them with your own rules, IAM policies, and target infrastructure.

Route events to a Kinesis stream

Event-driven architectures often capture events in a stream for downstream processing or analytics.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const console = new aws.cloudwatch.EventRule("console", {
    name: "capture-ec2-scaling-events",
    description: "Capture all EC2 scaling events",
    eventPattern: JSON.stringify({
        source: ["aws.autoscaling"],
        "detail-type": [
            "EC2 Instance Launch Successful",
            "EC2 Instance Terminate Successful",
            "EC2 Instance Launch Unsuccessful",
            "EC2 Instance Terminate Unsuccessful",
        ],
    }),
});
const testStream = new aws.kinesis.Stream("test_stream", {
    name: "kinesis-test",
    shardCount: 1,
});
const yada = new aws.cloudwatch.EventTarget("yada", {
    targetId: "Yada",
    rule: console.name,
    arn: testStream.arn,
    runCommandTargets: [
        {
            key: "tag:Name",
            values: ["FooBar"],
        },
        {
            key: "InstanceIds",
            values: ["i-162058cd308bffec2"],
        },
    ],
});
import pulumi
import json
import pulumi_aws as aws

console = aws.cloudwatch.EventRule("console",
    name="capture-ec2-scaling-events",
    description="Capture all EC2 scaling events",
    event_pattern=json.dumps({
        "source": ["aws.autoscaling"],
        "detail-type": [
            "EC2 Instance Launch Successful",
            "EC2 Instance Terminate Successful",
            "EC2 Instance Launch Unsuccessful",
            "EC2 Instance Terminate Unsuccessful",
        ],
    }))
test_stream = aws.kinesis.Stream("test_stream",
    name="kinesis-test",
    shard_count=1)
yada = aws.cloudwatch.EventTarget("yada",
    target_id="Yada",
    rule=console.name,
    arn=test_stream.arn,
    run_command_targets=[
        {
            "key": "tag:Name",
            "values": ["FooBar"],
        },
        {
            "key": "InstanceIds",
            "values": ["i-162058cd308bffec2"],
        },
    ])
package main

import (
	"encoding/json"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cloudwatch"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/kinesis"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		tmpJSON0, err := json.Marshal(map[string]interface{}{
			"source": []string{
				"aws.autoscaling",
			},
			"detail-type": []string{
				"EC2 Instance Launch Successful",
				"EC2 Instance Terminate Successful",
				"EC2 Instance Launch Unsuccessful",
				"EC2 Instance Terminate Unsuccessful",
			},
		})
		if err != nil {
			return err
		}
		json0 := string(tmpJSON0)
		console, err := cloudwatch.NewEventRule(ctx, "console", &cloudwatch.EventRuleArgs{
			Name:         pulumi.String("capture-ec2-scaling-events"),
			Description:  pulumi.String("Capture all EC2 scaling events"),
			EventPattern: pulumi.String(json0),
		})
		if err != nil {
			return err
		}
		testStream, err := kinesis.NewStream(ctx, "test_stream", &kinesis.StreamArgs{
			Name:       pulumi.String("kinesis-test"),
			ShardCount: pulumi.Int(1),
		})
		if err != nil {
			return err
		}
		_, err = cloudwatch.NewEventTarget(ctx, "yada", &cloudwatch.EventTargetArgs{
			TargetId: pulumi.String("Yada"),
			Rule:     console.Name,
			Arn:      testStream.Arn,
			RunCommandTargets: cloudwatch.EventTargetRunCommandTargetArray{
				&cloudwatch.EventTargetRunCommandTargetArgs{
					Key: pulumi.String("tag:Name"),
					Values: pulumi.StringArray{
						pulumi.String("FooBar"),
					},
				},
				&cloudwatch.EventTargetRunCommandTargetArgs{
					Key: pulumi.String("InstanceIds"),
					Values: pulumi.StringArray{
						pulumi.String("i-162058cd308bffec2"),
					},
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var console = new Aws.CloudWatch.EventRule("console", new()
    {
        Name = "capture-ec2-scaling-events",
        Description = "Capture all EC2 scaling events",
        EventPattern = JsonSerializer.Serialize(new Dictionary<string, object?>
        {
            ["source"] = new[]
            {
                "aws.autoscaling",
            },
            ["detail-type"] = new[]
            {
                "EC2 Instance Launch Successful",
                "EC2 Instance Terminate Successful",
                "EC2 Instance Launch Unsuccessful",
                "EC2 Instance Terminate Unsuccessful",
            },
        }),
    });

    var testStream = new Aws.Kinesis.Stream("test_stream", new()
    {
        Name = "kinesis-test",
        ShardCount = 1,
    });

    var yada = new Aws.CloudWatch.EventTarget("yada", new()
    {
        TargetId = "Yada",
        Rule = console.Name,
        Arn = testStream.Arn,
        RunCommandTargets = new[]
        {
            new Aws.CloudWatch.Inputs.EventTargetRunCommandTargetArgs
            {
                Key = "tag:Name",
                Values = new[]
                {
                    "FooBar",
                },
            },
            new Aws.CloudWatch.Inputs.EventTargetRunCommandTargetArgs
            {
                Key = "InstanceIds",
                Values = new[]
                {
                    "i-162058cd308bffec2",
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.cloudwatch.EventRule;
import com.pulumi.aws.cloudwatch.EventRuleArgs;
import com.pulumi.aws.kinesis.Stream;
import com.pulumi.aws.kinesis.StreamArgs;
import com.pulumi.aws.cloudwatch.EventTarget;
import com.pulumi.aws.cloudwatch.EventTargetArgs;
import com.pulumi.aws.cloudwatch.inputs.EventTargetRunCommandTargetArgs;
import static com.pulumi.codegen.internal.Serialization.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var console = new EventRule("console", EventRuleArgs.builder()
            .name("capture-ec2-scaling-events")
            .description("Capture all EC2 scaling events")
            .eventPattern(serializeJson(
                jsonObject(
                    jsonProperty("source", jsonArray("aws.autoscaling")),
                    jsonProperty("detail-type", jsonArray(
                        "EC2 Instance Launch Successful", 
                        "EC2 Instance Terminate Successful", 
                        "EC2 Instance Launch Unsuccessful", 
                        "EC2 Instance Terminate Unsuccessful"
                    ))
                )))
            .build());

        var testStream = new Stream("testStream", StreamArgs.builder()
            .name("kinesis-test")
            .shardCount(1)
            .build());

        var yada = new EventTarget("yada", EventTargetArgs.builder()
            .targetId("Yada")
            .rule(console.name())
            .arn(testStream.arn())
            .runCommandTargets(            
                EventTargetRunCommandTargetArgs.builder()
                    .key("tag:Name")
                    .values("FooBar")
                    .build(),
                EventTargetRunCommandTargetArgs.builder()
                    .key("InstanceIds")
                    .values("i-162058cd308bffec2")
                    .build())
            .build());

    }
}
resources:
  yada:
    type: aws:cloudwatch:EventTarget
    properties:
      targetId: Yada
      rule: ${console.name}
      arn: ${testStream.arn}
      runCommandTargets:
        - key: tag:Name
          values:
            - FooBar
        - key: InstanceIds
          values:
            - i-162058cd308bffec2
  console:
    type: aws:cloudwatch:EventRule
    properties:
      name: capture-ec2-scaling-events
      description: Capture all EC2 scaling events
      eventPattern:
        fn::toJSON:
          source:
            - aws.autoscaling
          detail-type:
            - EC2 Instance Launch Successful
            - EC2 Instance Terminate Successful
            - EC2 Instance Launch Unsuccessful
            - EC2 Instance Terminate Unsuccessful
  testStream:
    type: aws:kinesis:Stream
    name: test_stream
    properties:
      name: kinesis-test
      shardCount: 1

When the rule matches an event, EventBridge sends it to the Kinesis stream specified in the arn property. The targetId provides a unique identifier for this target within the rule. The runCommandTargets property shown here is specific to SSM targets and isn’t used for Kinesis routing.

Invoke SSM documents on tagged instances

Operations teams run commands on EC2 instances based on schedules or events using SSM documents.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const ssmLifecycleTrust = aws.iam.getPolicyDocument({
    statements: [{
        actions: ["sts:AssumeRole"],
        principals: [{
            type: "Service",
            identifiers: ["events.amazonaws.com"],
        }],
    }],
});
const stopInstance = new aws.ssm.Document("stop_instance", {
    name: "stop_instance",
    documentType: "Command",
    content: JSON.stringify({
        schemaVersion: "1.2",
        description: "Stop an instance",
        parameters: {},
        runtimeConfig: {
            "aws:runShellScript": {
                properties: [{
                    id: "0.aws:runShellScript",
                    runCommand: ["halt"],
                }],
            },
        },
    }),
});
const ssmLifecycle = aws.iam.getPolicyDocumentOutput({
    statements: [
        {
            effect: "Allow",
            actions: ["ssm:SendCommand"],
            resources: ["arn:aws:ec2:eu-west-1:1234567890:instance/*"],
            conditions: [{
                test: "StringEquals",
                variable: "ec2:ResourceTag/Terminate",
                values: ["*"],
            }],
        },
        {
            effect: "Allow",
            actions: ["ssm:SendCommand"],
            resources: [stopInstance.arn],
        },
    ],
});
const ssmLifecycleRole = new aws.iam.Role("ssm_lifecycle", {
    name: "SSMLifecycle",
    assumeRolePolicy: ssmLifecycleTrust.then(ssmLifecycleTrust => ssmLifecycleTrust.json),
});
const ssmLifecyclePolicy = new aws.iam.Policy("ssm_lifecycle", {
    name: "SSMLifecycle",
    policy: ssmLifecycle.apply(ssmLifecycle => ssmLifecycle.json),
});
const ssmLifecycleRolePolicyAttachment = new aws.iam.RolePolicyAttachment("ssm_lifecycle", {
    policyArn: ssmLifecyclePolicy.arn,
    role: ssmLifecycleRole.name,
});
const stopInstances = new aws.cloudwatch.EventRule("stop_instances", {
    name: "StopInstance",
    description: "Stop instances nightly",
    scheduleExpression: "cron(0 0 * * ? *)",
});
const stopInstancesEventTarget = new aws.cloudwatch.EventTarget("stop_instances", {
    targetId: "StopInstance",
    arn: stopInstance.arn,
    rule: stopInstances.name,
    roleArn: ssmLifecycleRole.arn,
    runCommandTargets: [{
        key: "tag:Terminate",
        values: ["midnight"],
    }],
});
import pulumi
import json
import pulumi_aws as aws

ssm_lifecycle_trust = aws.iam.get_policy_document(statements=[{
    "actions": ["sts:AssumeRole"],
    "principals": [{
        "type": "Service",
        "identifiers": ["events.amazonaws.com"],
    }],
}])
stop_instance = aws.ssm.Document("stop_instance",
    name="stop_instance",
    document_type="Command",
    content=json.dumps({
        "schemaVersion": "1.2",
        "description": "Stop an instance",
        "parameters": {},
        "runtimeConfig": {
            "aws:runShellScript": {
                "properties": [{
                    "id": "0.aws:runShellScript",
                    "runCommand": ["halt"],
                }],
            },
        },
    }))
ssm_lifecycle = aws.iam.get_policy_document_output(statements=[
    {
        "effect": "Allow",
        "actions": ["ssm:SendCommand"],
        "resources": ["arn:aws:ec2:eu-west-1:1234567890:instance/*"],
        "conditions": [{
            "test": "StringEquals",
            "variable": "ec2:ResourceTag/Terminate",
            "values": ["*"],
        }],
    },
    {
        "effect": "Allow",
        "actions": ["ssm:SendCommand"],
        "resources": [stop_instance.arn],
    },
])
ssm_lifecycle_role = aws.iam.Role("ssm_lifecycle",
    name="SSMLifecycle",
    assume_role_policy=ssm_lifecycle_trust.json)
ssm_lifecycle_policy = aws.iam.Policy("ssm_lifecycle",
    name="SSMLifecycle",
    policy=ssm_lifecycle.json)
ssm_lifecycle_role_policy_attachment = aws.iam.RolePolicyAttachment("ssm_lifecycle",
    policy_arn=ssm_lifecycle_policy.arn,
    role=ssm_lifecycle_role.name)
stop_instances = aws.cloudwatch.EventRule("stop_instances",
    name="StopInstance",
    description="Stop instances nightly",
    schedule_expression="cron(0 0 * * ? *)")
stop_instances_event_target = aws.cloudwatch.EventTarget("stop_instances",
    target_id="StopInstance",
    arn=stop_instance.arn,
    rule=stop_instances.name,
    role_arn=ssm_lifecycle_role.arn,
    run_command_targets=[{
        "key": "tag:Terminate",
        "values": ["midnight"],
    }])
package main

import (
	"encoding/json"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cloudwatch"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ssm"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		ssmLifecycleTrust, err := iam.GetPolicyDocument(ctx, &iam.GetPolicyDocumentArgs{
			Statements: []iam.GetPolicyDocumentStatement{
				{
					Actions: []string{
						"sts:AssumeRole",
					},
					Principals: []iam.GetPolicyDocumentStatementPrincipal{
						{
							Type: "Service",
							Identifiers: []string{
								"events.amazonaws.com",
							},
						},
					},
				},
			},
		}, nil)
		if err != nil {
			return err
		}
		tmpJSON0, err := json.Marshal(map[string]interface{}{
			"schemaVersion": "1.2",
			"description":   "Stop an instance",
			"parameters":    map[string]interface{}{},
			"runtimeConfig": map[string]interface{}{
				"aws:runShellScript": map[string]interface{}{
					"properties": []map[string]interface{}{
						map[string]interface{}{
							"id": "0.aws:runShellScript",
							"runCommand": []string{
								"halt",
							},
						},
					},
				},
			},
		})
		if err != nil {
			return err
		}
		json0 := string(tmpJSON0)
		stopInstance, err := ssm.NewDocument(ctx, "stop_instance", &ssm.DocumentArgs{
			Name:         pulumi.String("stop_instance"),
			DocumentType: pulumi.String("Command"),
			Content:      pulumi.String(json0),
		})
		if err != nil {
			return err
		}
		ssmLifecycle := iam.GetPolicyDocumentOutput(ctx, iam.GetPolicyDocumentOutputArgs{
			Statements: iam.GetPolicyDocumentStatementArray{
				&iam.GetPolicyDocumentStatementArgs{
					Effect: pulumi.String("Allow"),
					Actions: pulumi.StringArray{
						pulumi.String("ssm:SendCommand"),
					},
					Resources: pulumi.StringArray{
						pulumi.String("arn:aws:ec2:eu-west-1:1234567890:instance/*"),
					},
					Conditions: iam.GetPolicyDocumentStatementConditionArray{
						&iam.GetPolicyDocumentStatementConditionArgs{
							Test:     pulumi.String("StringEquals"),
							Variable: pulumi.String("ec2:ResourceTag/Terminate"),
							Values: pulumi.StringArray{
								pulumi.String("*"),
							},
						},
					},
				},
				&iam.GetPolicyDocumentStatementArgs{
					Effect: pulumi.String("Allow"),
					Actions: pulumi.StringArray{
						pulumi.String("ssm:SendCommand"),
					},
					Resources: pulumi.StringArray{
						stopInstance.Arn,
					},
				},
			},
		}, nil)
		ssmLifecycleRole, err := iam.NewRole(ctx, "ssm_lifecycle", &iam.RoleArgs{
			Name:             pulumi.String("SSMLifecycle"),
			AssumeRolePolicy: pulumi.String(ssmLifecycleTrust.Json),
		})
		if err != nil {
			return err
		}
		ssmLifecyclePolicy, err := iam.NewPolicy(ctx, "ssm_lifecycle", &iam.PolicyArgs{
			Name: pulumi.String("SSMLifecycle"),
			Policy: pulumi.String(ssmLifecycle.ApplyT(func(ssmLifecycle iam.GetPolicyDocumentResult) (*string, error) {
				return &ssmLifecycle.Json, nil
			}).(pulumi.StringPtrOutput)),
		})
		if err != nil {
			return err
		}
		_, err = iam.NewRolePolicyAttachment(ctx, "ssm_lifecycle", &iam.RolePolicyAttachmentArgs{
			PolicyArn: ssmLifecyclePolicy.Arn,
			Role:      ssmLifecycleRole.Name,
		})
		if err != nil {
			return err
		}
		stopInstances, err := cloudwatch.NewEventRule(ctx, "stop_instances", &cloudwatch.EventRuleArgs{
			Name:               pulumi.String("StopInstance"),
			Description:        pulumi.String("Stop instances nightly"),
			ScheduleExpression: pulumi.String("cron(0 0 * * ? *)"),
		})
		if err != nil {
			return err
		}
		_, err = cloudwatch.NewEventTarget(ctx, "stop_instances", &cloudwatch.EventTargetArgs{
			TargetId: pulumi.String("StopInstance"),
			Arn:      stopInstance.Arn,
			Rule:     stopInstances.Name,
			RoleArn:  ssmLifecycleRole.Arn,
			RunCommandTargets: cloudwatch.EventTargetRunCommandTargetArray{
				&cloudwatch.EventTargetRunCommandTargetArgs{
					Key: pulumi.String("tag:Terminate"),
					Values: pulumi.StringArray{
						pulumi.String("midnight"),
					},
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var ssmLifecycleTrust = Aws.Iam.GetPolicyDocument.Invoke(new()
    {
        Statements = new[]
        {
            new Aws.Iam.Inputs.GetPolicyDocumentStatementInputArgs
            {
                Actions = new[]
                {
                    "sts:AssumeRole",
                },
                Principals = new[]
                {
                    new Aws.Iam.Inputs.GetPolicyDocumentStatementPrincipalInputArgs
                    {
                        Type = "Service",
                        Identifiers = new[]
                        {
                            "events.amazonaws.com",
                        },
                    },
                },
            },
        },
    });

    var stopInstance = new Aws.Ssm.Document("stop_instance", new()
    {
        Name = "stop_instance",
        DocumentType = "Command",
        Content = JsonSerializer.Serialize(new Dictionary<string, object?>
        {
            ["schemaVersion"] = "1.2",
            ["description"] = "Stop an instance",
            ["parameters"] = new Dictionary<string, object?>
            {
            },
            ["runtimeConfig"] = new Dictionary<string, object?>
            {
                ["aws:runShellScript"] = new Dictionary<string, object?>
                {
                    ["properties"] = new[]
                    {
                        new Dictionary<string, object?>
                        {
                            ["id"] = "0.aws:runShellScript",
                            ["runCommand"] = new[]
                            {
                                "halt",
                            },
                        },
                    },
                },
            },
        }),
    });

    var ssmLifecycle = Aws.Iam.GetPolicyDocument.Invoke(new()
    {
        Statements = new[]
        {
            new Aws.Iam.Inputs.GetPolicyDocumentStatementInputArgs
            {
                Effect = "Allow",
                Actions = new[]
                {
                    "ssm:SendCommand",
                },
                Resources = new[]
                {
                    "arn:aws:ec2:eu-west-1:1234567890:instance/*",
                },
                Conditions = new[]
                {
                    new Aws.Iam.Inputs.GetPolicyDocumentStatementConditionInputArgs
                    {
                        Test = "StringEquals",
                        Variable = "ec2:ResourceTag/Terminate",
                        Values = new[]
                        {
                            "*",
                        },
                    },
                },
            },
            new Aws.Iam.Inputs.GetPolicyDocumentStatementInputArgs
            {
                Effect = "Allow",
                Actions = new[]
                {
                    "ssm:SendCommand",
                },
                Resources = new[]
                {
                    stopInstance.Arn,
                },
            },
        },
    });

    var ssmLifecycleRole = new Aws.Iam.Role("ssm_lifecycle", new()
    {
        Name = "SSMLifecycle",
        AssumeRolePolicy = ssmLifecycleTrust.Apply(getPolicyDocumentResult => getPolicyDocumentResult.Json),
    });

    var ssmLifecyclePolicy = new Aws.Iam.Policy("ssm_lifecycle", new()
    {
        Name = "SSMLifecycle",
        PolicyDocument = ssmLifecycle.Apply(getPolicyDocumentResult => getPolicyDocumentResult.Json),
    });

    var ssmLifecycleRolePolicyAttachment = new Aws.Iam.RolePolicyAttachment("ssm_lifecycle", new()
    {
        PolicyArn = ssmLifecyclePolicy.Arn,
        Role = ssmLifecycleRole.Name,
    });

    var stopInstances = new Aws.CloudWatch.EventRule("stop_instances", new()
    {
        Name = "StopInstance",
        Description = "Stop instances nightly",
        ScheduleExpression = "cron(0 0 * * ? *)",
    });

    var stopInstancesEventTarget = new Aws.CloudWatch.EventTarget("stop_instances", new()
    {
        TargetId = "StopInstance",
        Arn = stopInstance.Arn,
        Rule = stopInstances.Name,
        RoleArn = ssmLifecycleRole.Arn,
        RunCommandTargets = new[]
        {
            new Aws.CloudWatch.Inputs.EventTargetRunCommandTargetArgs
            {
                Key = "tag:Terminate",
                Values = new[]
                {
                    "midnight",
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.iam.IamFunctions;
import com.pulumi.aws.iam.inputs.GetPolicyDocumentArgs;
import com.pulumi.aws.ssm.Document;
import com.pulumi.aws.ssm.DocumentArgs;
import com.pulumi.aws.iam.Role;
import com.pulumi.aws.iam.RoleArgs;
import com.pulumi.aws.iam.Policy;
import com.pulumi.aws.iam.PolicyArgs;
import com.pulumi.aws.iam.RolePolicyAttachment;
import com.pulumi.aws.iam.RolePolicyAttachmentArgs;
import com.pulumi.aws.cloudwatch.EventRule;
import com.pulumi.aws.cloudwatch.EventRuleArgs;
import com.pulumi.aws.cloudwatch.EventTarget;
import com.pulumi.aws.cloudwatch.EventTargetArgs;
import com.pulumi.aws.cloudwatch.inputs.EventTargetRunCommandTargetArgs;
import static com.pulumi.codegen.internal.Serialization.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        final var ssmLifecycleTrust = IamFunctions.getPolicyDocument(GetPolicyDocumentArgs.builder()
            .statements(GetPolicyDocumentStatementArgs.builder()
                .actions("sts:AssumeRole")
                .principals(GetPolicyDocumentStatementPrincipalArgs.builder()
                    .type("Service")
                    .identifiers("events.amazonaws.com")
                    .build())
                .build())
            .build());

        var stopInstance = new Document("stopInstance", DocumentArgs.builder()
            .name("stop_instance")
            .documentType("Command")
            .content(serializeJson(
                jsonObject(
                    jsonProperty("schemaVersion", "1.2"),
                    jsonProperty("description", "Stop an instance"),
                    jsonProperty("parameters", jsonObject(

                    )),
                    jsonProperty("runtimeConfig", jsonObject(
                        jsonProperty("aws:runShellScript", jsonObject(
                            jsonProperty("properties", jsonArray(jsonObject(
                                jsonProperty("id", "0.aws:runShellScript"),
                                jsonProperty("runCommand", jsonArray("halt"))
                            )))
                        ))
                    ))
                )))
            .build());

        final var ssmLifecycle = IamFunctions.getPolicyDocument(GetPolicyDocumentArgs.builder()
            .statements(            
                GetPolicyDocumentStatementArgs.builder()
                    .effect("Allow")
                    .actions("ssm:SendCommand")
                    .resources("arn:aws:ec2:eu-west-1:1234567890:instance/*")
                    .conditions(GetPolicyDocumentStatementConditionArgs.builder()
                        .test("StringEquals")
                        .variable("ec2:ResourceTag/Terminate")
                        .values("*")
                        .build())
                    .build(),
                GetPolicyDocumentStatementArgs.builder()
                    .effect("Allow")
                    .actions("ssm:SendCommand")
                    .resources(stopInstance.arn())
                    .build())
            .build());

        var ssmLifecycleRole = new Role("ssmLifecycleRole", RoleArgs.builder()
            .name("SSMLifecycle")
            .assumeRolePolicy(ssmLifecycleTrust.json())
            .build());

        var ssmLifecyclePolicy = new Policy("ssmLifecyclePolicy", PolicyArgs.builder()
            .name("SSMLifecycle")
            .policy(ssmLifecycle.applyValue(_ssmLifecycle -> _ssmLifecycle.json()))
            .build());

        var ssmLifecycleRolePolicyAttachment = new RolePolicyAttachment("ssmLifecycleRolePolicyAttachment", RolePolicyAttachmentArgs.builder()
            .policyArn(ssmLifecyclePolicy.arn())
            .role(ssmLifecycleRole.name())
            .build());

        var stopInstances = new EventRule("stopInstances", EventRuleArgs.builder()
            .name("StopInstance")
            .description("Stop instances nightly")
            .scheduleExpression("cron(0 0 * * ? *)")
            .build());

        var stopInstancesEventTarget = new EventTarget("stopInstancesEventTarget", EventTargetArgs.builder()
            .targetId("StopInstance")
            .arn(stopInstance.arn())
            .rule(stopInstances.name())
            .roleArn(ssmLifecycleRole.arn())
            .runCommandTargets(EventTargetRunCommandTargetArgs.builder()
                .key("tag:Terminate")
                .values("midnight")
                .build())
            .build());

    }
}
resources:
  ssmLifecycleRole:
    type: aws:iam:Role
    name: ssm_lifecycle
    properties:
      name: SSMLifecycle
      assumeRolePolicy: ${ssmLifecycleTrust.json}
  ssmLifecyclePolicy:
    type: aws:iam:Policy
    name: ssm_lifecycle
    properties:
      name: SSMLifecycle
      policy: ${ssmLifecycle.json}
  ssmLifecycleRolePolicyAttachment:
    type: aws:iam:RolePolicyAttachment
    name: ssm_lifecycle
    properties:
      policyArn: ${ssmLifecyclePolicy.arn}
      role: ${ssmLifecycleRole.name}
  stopInstance:
    type: aws:ssm:Document
    name: stop_instance
    properties:
      name: stop_instance
      documentType: Command
      content:
        fn::toJSON:
          schemaVersion: '1.2'
          description: Stop an instance
          parameters: {}
          runtimeConfig:
            aws:runShellScript:
              properties:
                - id: 0.aws:runShellScript
                  runCommand:
                    - halt
  stopInstances:
    type: aws:cloudwatch:EventRule
    name: stop_instances
    properties:
      name: StopInstance
      description: Stop instances nightly
      scheduleExpression: cron(0 0 * * ? *)
  stopInstancesEventTarget:
    type: aws:cloudwatch:EventTarget
    name: stop_instances
    properties:
      targetId: StopInstance
      arn: ${stopInstance.arn}
      rule: ${stopInstances.name}
      roleArn: ${ssmLifecycleRole.arn}
      runCommandTargets:
        - key: tag:Terminate
          values:
            - midnight
variables:
  ssmLifecycleTrust:
    fn::invoke:
      function: aws:iam:getPolicyDocument
      arguments:
        statements:
          - actions:
              - sts:AssumeRole
            principals:
              - type: Service
                identifiers:
                  - events.amazonaws.com
  ssmLifecycle:
    fn::invoke:
      function: aws:iam:getPolicyDocument
      arguments:
        statements:
          - effect: Allow
            actions:
              - ssm:SendCommand
            resources:
              - arn:aws:ec2:eu-west-1:1234567890:instance/*
            conditions:
              - test: StringEquals
                variable: ec2:ResourceTag/Terminate
                values:
                  - '*'
          - effect: Allow
            actions:
              - ssm:SendCommand
            resources:
              - ${stopInstance.arn}

The runCommandTargets property selects instances by tag (key “tag:Terminate”, value “midnight”). The roleArn grants EventBridge permission to invoke SSM SendCommand. When the scheduled rule fires, SSM executes the document on all matching instances.

Run ECS tasks with container overrides

Scheduled batch jobs or event-driven workloads often run as ECS tasks with custom commands.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as std from "@pulumi/std";

const assumeRole = aws.iam.getPolicyDocument({
    statements: [{
        effect: "Allow",
        principals: [{
            type: "Service",
            identifiers: ["events.amazonaws.com"],
        }],
        actions: ["sts:AssumeRole"],
    }],
});
const ecsEvents = new aws.iam.Role("ecs_events", {
    name: "ecs_events",
    assumeRolePolicy: assumeRole.then(assumeRole => assumeRole.json),
});
const ecsEventsRunTaskWithAnyRole = std.replace({
    text: taskName.arn,
    search: "/:\\d+$/",
    replace: ":*",
}).then(invoke => aws.iam.getPolicyDocument({
    statements: [
        {
            effect: "Allow",
            actions: ["iam:PassRole"],
            resources: ["*"],
        },
        {
            effect: "Allow",
            actions: ["ecs:RunTask"],
            resources: [invoke.result],
        },
    ],
}));
const ecsEventsRunTaskWithAnyRoleRolePolicy = new aws.iam.RolePolicy("ecs_events_run_task_with_any_role", {
    name: "ecs_events_run_task_with_any_role",
    role: ecsEvents.id,
    policy: ecsEventsRunTaskWithAnyRole.then(ecsEventsRunTaskWithAnyRole => ecsEventsRunTaskWithAnyRole.json),
});
const ecsScheduledTask = new aws.cloudwatch.EventTarget("ecs_scheduled_task", {
    targetId: "run-scheduled-task-every-hour",
    arn: clusterName.arn,
    rule: everyHour.name,
    roleArn: ecsEvents.arn,
    ecsTarget: {
        taskCount: 1,
        taskDefinitionArn: taskName.arn,
    },
    input: JSON.stringify({
        containerOverrides: [{
            name: "name-of-container-to-override",
            command: [
                "bin/console",
                "scheduled-task",
            ],
        }],
    }),
});
import pulumi
import json
import pulumi_aws as aws
import pulumi_std as std

assume_role = aws.iam.get_policy_document(statements=[{
    "effect": "Allow",
    "principals": [{
        "type": "Service",
        "identifiers": ["events.amazonaws.com"],
    }],
    "actions": ["sts:AssumeRole"],
}])
ecs_events = aws.iam.Role("ecs_events",
    name="ecs_events",
    assume_role_policy=assume_role.json)
ecs_events_run_task_with_any_role = aws.iam.get_policy_document(statements=[
    {
        "effect": "Allow",
        "actions": ["iam:PassRole"],
        "resources": ["*"],
    },
    {
        "effect": "Allow",
        "actions": ["ecs:RunTask"],
        "resources": [std.replace(text=task_name["arn"],
            search="/:\\d+$/",
            replace=":*").result],
    },
])
ecs_events_run_task_with_any_role_role_policy = aws.iam.RolePolicy("ecs_events_run_task_with_any_role",
    name="ecs_events_run_task_with_any_role",
    role=ecs_events.id,
    policy=ecs_events_run_task_with_any_role.json)
ecs_scheduled_task = aws.cloudwatch.EventTarget("ecs_scheduled_task",
    target_id="run-scheduled-task-every-hour",
    arn=cluster_name["arn"],
    rule=every_hour["name"],
    role_arn=ecs_events.arn,
    ecs_target={
        "task_count": 1,
        "task_definition_arn": task_name["arn"],
    },
    input=json.dumps({
        "containerOverrides": [{
            "name": "name-of-container-to-override",
            "command": [
                "bin/console",
                "scheduled-task",
            ],
        }],
    }))
package main

import (
	"encoding/json"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cloudwatch"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
	"github.com/pulumi/pulumi-std/sdk/go/std"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
assumeRole, err := iam.GetPolicyDocument(ctx, &iam.GetPolicyDocumentArgs{
Statements: []iam.GetPolicyDocumentStatement{
{
Effect: pulumi.StringRef("Allow"),
Principals: []iam.GetPolicyDocumentStatementPrincipal{
{
Type: "Service",
Identifiers: []string{
"events.amazonaws.com",
},
},
},
Actions: []string{
"sts:AssumeRole",
},
},
},
}, nil);
if err != nil {
return err
}
ecsEvents, err := iam.NewRole(ctx, "ecs_events", &iam.RoleArgs{
Name: pulumi.String("ecs_events"),
AssumeRolePolicy: pulumi.String(assumeRole.Json),
})
if err != nil {
return err
}
ecsEventsRunTaskWithAnyRole, err := iam.GetPolicyDocument(ctx, &iam.GetPolicyDocumentArgs{
Statements: []iam.GetPolicyDocumentStatement{
{
Effect: pulumi.StringRef("Allow"),
Actions: []string{
"iam:PassRole",
},
Resources: []string{
"*",
},
},
{
Effect: pulumi.StringRef("Allow"),
Actions: []string{
"ecs:RunTask",
},
Resources: interface{}{
std.Replace(ctx, {
Text: taskName.Arn,
Search: "/:\\d+$/",
Replace: ":*",
}, nil).Result,
},
},
},
}, nil);
if err != nil {
return err
}
_, err = iam.NewRolePolicy(ctx, "ecs_events_run_task_with_any_role", &iam.RolePolicyArgs{
Name: pulumi.String("ecs_events_run_task_with_any_role"),
Role: ecsEvents.ID(),
Policy: pulumi.String(ecsEventsRunTaskWithAnyRole.Json),
})
if err != nil {
return err
}
tmpJSON0, err := json.Marshal(map[string]interface{}{
"containerOverrides": []map[string]interface{}{
map[string]interface{}{
"name": "name-of-container-to-override",
"command": []string{
"bin/console",
"scheduled-task",
},
},
},
})
if err != nil {
return err
}
json0 := string(tmpJSON0)
_, err = cloudwatch.NewEventTarget(ctx, "ecs_scheduled_task", &cloudwatch.EventTargetArgs{
TargetId: pulumi.String("run-scheduled-task-every-hour"),
Arn: pulumi.Any(clusterName.Arn),
Rule: pulumi.Any(everyHour.Name),
RoleArn: ecsEvents.Arn,
EcsTarget: &cloudwatch.EventTargetEcsTargetArgs{
TaskCount: pulumi.Int(1),
TaskDefinitionArn: pulumi.Any(taskName.Arn),
},
Input: pulumi.String(json0),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Pulumi;
using Aws = Pulumi.Aws;
using Std = Pulumi.Std;

return await Deployment.RunAsync(() => 
{
    var assumeRole = Aws.Iam.GetPolicyDocument.Invoke(new()
    {
        Statements = new[]
        {
            new Aws.Iam.Inputs.GetPolicyDocumentStatementInputArgs
            {
                Effect = "Allow",
                Principals = new[]
                {
                    new Aws.Iam.Inputs.GetPolicyDocumentStatementPrincipalInputArgs
                    {
                        Type = "Service",
                        Identifiers = new[]
                        {
                            "events.amazonaws.com",
                        },
                    },
                },
                Actions = new[]
                {
                    "sts:AssumeRole",
                },
            },
        },
    });

    var ecsEvents = new Aws.Iam.Role("ecs_events", new()
    {
        Name = "ecs_events",
        AssumeRolePolicy = assumeRole.Apply(getPolicyDocumentResult => getPolicyDocumentResult.Json),
    });

    var ecsEventsRunTaskWithAnyRole = Aws.Iam.GetPolicyDocument.Invoke(new()
    {
        Statements = new[]
        {
            new Aws.Iam.Inputs.GetPolicyDocumentStatementInputArgs
            {
                Effect = "Allow",
                Actions = new[]
                {
                    "iam:PassRole",
                },
                Resources = new[]
                {
                    "*",
                },
            },
            new Aws.Iam.Inputs.GetPolicyDocumentStatementInputArgs
            {
                Effect = "Allow",
                Actions = new[]
                {
                    "ecs:RunTask",
                },
                Resources = new[]
                {
                    Std.Replace.Invoke(new()
                    {
                        Text = taskName.Arn,
                        Search = "/:\\d+$/",
                        Replace = ":*",
                    }).Result,
                },
            },
        },
    });

    var ecsEventsRunTaskWithAnyRoleRolePolicy = new Aws.Iam.RolePolicy("ecs_events_run_task_with_any_role", new()
    {
        Name = "ecs_events_run_task_with_any_role",
        Role = ecsEvents.Id,
        Policy = ecsEventsRunTaskWithAnyRole.Apply(getPolicyDocumentResult => getPolicyDocumentResult.Json),
    });

    var ecsScheduledTask = new Aws.CloudWatch.EventTarget("ecs_scheduled_task", new()
    {
        TargetId = "run-scheduled-task-every-hour",
        Arn = clusterName.Arn,
        Rule = everyHour.Name,
        RoleArn = ecsEvents.Arn,
        EcsTarget = new Aws.CloudWatch.Inputs.EventTargetEcsTargetArgs
        {
            TaskCount = 1,
            TaskDefinitionArn = taskName.Arn,
        },
        Input = JsonSerializer.Serialize(new Dictionary<string, object?>
        {
            ["containerOverrides"] = new[]
            {
                new Dictionary<string, object?>
                {
                    ["name"] = "name-of-container-to-override",
                    ["command"] = new[]
                    {
                        "bin/console",
                        "scheduled-task",
                    },
                },
            },
        }),
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.iam.IamFunctions;
import com.pulumi.aws.iam.inputs.GetPolicyDocumentArgs;
import com.pulumi.aws.iam.Role;
import com.pulumi.aws.iam.RoleArgs;
import com.pulumi.std.StdFunctions;
import com.pulumi.std.inputs.ReplaceArgs;
import com.pulumi.aws.iam.RolePolicy;
import com.pulumi.aws.iam.RolePolicyArgs;
import com.pulumi.aws.cloudwatch.EventTarget;
import com.pulumi.aws.cloudwatch.EventTargetArgs;
import com.pulumi.aws.cloudwatch.inputs.EventTargetEcsTargetArgs;
import static com.pulumi.codegen.internal.Serialization.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        final var assumeRole = IamFunctions.getPolicyDocument(GetPolicyDocumentArgs.builder()
            .statements(GetPolicyDocumentStatementArgs.builder()
                .effect("Allow")
                .principals(GetPolicyDocumentStatementPrincipalArgs.builder()
                    .type("Service")
                    .identifiers("events.amazonaws.com")
                    .build())
                .actions("sts:AssumeRole")
                .build())
            .build());

        var ecsEvents = new Role("ecsEvents", RoleArgs.builder()
            .name("ecs_events")
            .assumeRolePolicy(assumeRole.json())
            .build());

        final var ecsEventsRunTaskWithAnyRole = IamFunctions.getPolicyDocument(GetPolicyDocumentArgs.builder()
            .statements(            
                GetPolicyDocumentStatementArgs.builder()
                    .effect("Allow")
                    .actions("iam:PassRole")
                    .resources("*")
                    .build(),
                GetPolicyDocumentStatementArgs.builder()
                    .effect("Allow")
                    .actions("ecs:RunTask")
                    .resources(StdFunctions.replace(ReplaceArgs.builder()
                        .text(taskName.arn())
                        .search("/:\\d+$/")
                        .replace(":*")
                        .build()).result())
                    .build())
            .build());

        var ecsEventsRunTaskWithAnyRoleRolePolicy = new RolePolicy("ecsEventsRunTaskWithAnyRoleRolePolicy", RolePolicyArgs.builder()
            .name("ecs_events_run_task_with_any_role")
            .role(ecsEvents.id())
            .policy(ecsEventsRunTaskWithAnyRole.json())
            .build());

        var ecsScheduledTask = new EventTarget("ecsScheduledTask", EventTargetArgs.builder()
            .targetId("run-scheduled-task-every-hour")
            .arn(clusterName.arn())
            .rule(everyHour.name())
            .roleArn(ecsEvents.arn())
            .ecsTarget(EventTargetEcsTargetArgs.builder()
                .taskCount(1)
                .taskDefinitionArn(taskName.arn())
                .build())
            .input(serializeJson(
                jsonObject(
                    jsonProperty("containerOverrides", jsonArray(jsonObject(
                        jsonProperty("name", "name-of-container-to-override"),
                        jsonProperty("command", jsonArray(
                            "bin/console", 
                            "scheduled-task"
                        ))
                    )))
                )))
            .build());

    }
}
resources:
  ecsEvents:
    type: aws:iam:Role
    name: ecs_events
    properties:
      name: ecs_events
      assumeRolePolicy: ${assumeRole.json}
  ecsEventsRunTaskWithAnyRoleRolePolicy:
    type: aws:iam:RolePolicy
    name: ecs_events_run_task_with_any_role
    properties:
      name: ecs_events_run_task_with_any_role
      role: ${ecsEvents.id}
      policy: ${ecsEventsRunTaskWithAnyRole.json}
  ecsScheduledTask:
    type: aws:cloudwatch:EventTarget
    name: ecs_scheduled_task
    properties:
      targetId: run-scheduled-task-every-hour
      arn: ${clusterName.arn}
      rule: ${everyHour.name}
      roleArn: ${ecsEvents.arn}
      ecsTarget:
        taskCount: 1
        taskDefinitionArn: ${taskName.arn}
      input:
        fn::toJSON:
          containerOverrides:
            - name: name-of-container-to-override
              command:
                - bin/console
                - scheduled-task
variables:
  assumeRole:
    fn::invoke:
      function: aws:iam:getPolicyDocument
      arguments:
        statements:
          - effect: Allow
            principals:
              - type: Service
                identifiers:
                  - events.amazonaws.com
            actions:
              - sts:AssumeRole
  ecsEventsRunTaskWithAnyRole:
    fn::invoke:
      function: aws:iam:getPolicyDocument
      arguments:
        statements:
          - effect: Allow
            actions:
              - iam:PassRole
            resources:
              - '*'
          - effect: Allow
            actions:
              - ecs:RunTask
            resources:
              - fn::invoke:
                  function: std:replace
                  arguments:
                    text: ${taskName.arn}
                    search: /:\d+$/
                    replace: :*
                  return: result

The ecsTarget property specifies the cluster and task definition. The input property provides a JSON object with containerOverrides that replace the default command in the named container. EventBridge launches the task with these overrides when the rule triggers.

Trigger API Gateway endpoints from events

Some workflows invoke HTTP APIs when events occur, passing event data as parameters.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const exampleEventRule = new aws.cloudwatch.EventRule("example", {});
const exampleDeployment = new aws.apigateway.Deployment("example", {restApi: exampleAwsApiGatewayRestApi.id});
const exampleStage = new aws.apigateway.Stage("example", {
    restApi: exampleAwsApiGatewayRestApi.id,
    deployment: exampleDeployment.id,
});
const example = new aws.cloudwatch.EventTarget("example", {
    arn: pulumi.interpolate`${exampleStage.executionArn}/GET`,
    rule: exampleEventRule.id,
    httpTarget: {
        queryStringParameters: {
            Body: "$.detail.body",
        },
        headerParameters: {
            Env: "Test",
        },
    },
});
import pulumi
import pulumi_aws as aws

example_event_rule = aws.cloudwatch.EventRule("example")
example_deployment = aws.apigateway.Deployment("example", rest_api=example_aws_api_gateway_rest_api["id"])
example_stage = aws.apigateway.Stage("example",
    rest_api=example_aws_api_gateway_rest_api["id"],
    deployment=example_deployment.id)
example = aws.cloudwatch.EventTarget("example",
    arn=example_stage.execution_arn.apply(lambda execution_arn: f"{execution_arn}/GET"),
    rule=example_event_rule.id,
    http_target={
        "query_string_parameters": {
            "Body": "$.detail.body",
        },
        "header_parameters": {
            "Env": "Test",
        },
    })
package main

import (
	"fmt"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/apigateway"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cloudwatch"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		exampleEventRule, err := cloudwatch.NewEventRule(ctx, "example", nil)
		if err != nil {
			return err
		}
		exampleDeployment, err := apigateway.NewDeployment(ctx, "example", &apigateway.DeploymentArgs{
			RestApi: pulumi.Any(exampleAwsApiGatewayRestApi.Id),
		})
		if err != nil {
			return err
		}
		exampleStage, err := apigateway.NewStage(ctx, "example", &apigateway.StageArgs{
			RestApi:    pulumi.Any(exampleAwsApiGatewayRestApi.Id),
			Deployment: exampleDeployment.ID(),
		})
		if err != nil {
			return err
		}
		_, err = cloudwatch.NewEventTarget(ctx, "example", &cloudwatch.EventTargetArgs{
			Arn: exampleStage.ExecutionArn.ApplyT(func(executionArn string) (string, error) {
				return fmt.Sprintf("%v/GET", executionArn), nil
			}).(pulumi.StringOutput),
			Rule: exampleEventRule.ID(),
			HttpTarget: &cloudwatch.EventTargetHttpTargetArgs{
				QueryStringParameters: pulumi.StringMap{
					"Body": pulumi.String("$.detail.body"),
				},
				HeaderParameters: pulumi.StringMap{
					"Env": pulumi.String("Test"),
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var exampleEventRule = new Aws.CloudWatch.EventRule("example");

    var exampleDeployment = new Aws.ApiGateway.Deployment("example", new()
    {
        RestApi = exampleAwsApiGatewayRestApi.Id,
    });

    var exampleStage = new Aws.ApiGateway.Stage("example", new()
    {
        RestApi = exampleAwsApiGatewayRestApi.Id,
        Deployment = exampleDeployment.Id,
    });

    var example = new Aws.CloudWatch.EventTarget("example", new()
    {
        Arn = exampleStage.ExecutionArn.Apply(executionArn => $"{executionArn}/GET"),
        Rule = exampleEventRule.Id,
        HttpTarget = new Aws.CloudWatch.Inputs.EventTargetHttpTargetArgs
        {
            QueryStringParameters = 
            {
                { "Body", "$.detail.body" },
            },
            HeaderParameters = 
            {
                { "Env", "Test" },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.cloudwatch.EventRule;
import com.pulumi.aws.apigateway.Deployment;
import com.pulumi.aws.apigateway.DeploymentArgs;
import com.pulumi.aws.apigateway.Stage;
import com.pulumi.aws.apigateway.StageArgs;
import com.pulumi.aws.cloudwatch.EventTarget;
import com.pulumi.aws.cloudwatch.EventTargetArgs;
import com.pulumi.aws.cloudwatch.inputs.EventTargetHttpTargetArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var exampleEventRule = new EventRule("exampleEventRule");

        var exampleDeployment = new Deployment("exampleDeployment", DeploymentArgs.builder()
            .restApi(exampleAwsApiGatewayRestApi.id())
            .build());

        var exampleStage = new Stage("exampleStage", StageArgs.builder()
            .restApi(exampleAwsApiGatewayRestApi.id())
            .deployment(exampleDeployment.id())
            .build());

        var example = new EventTarget("example", EventTargetArgs.builder()
            .arn(exampleStage.executionArn().applyValue(_executionArn -> String.format("%s/GET", _executionArn)))
            .rule(exampleEventRule.id())
            .httpTarget(EventTargetHttpTargetArgs.builder()
                .queryStringParameters(Map.of("Body", "$.detail.body"))
                .headerParameters(Map.of("Env", "Test"))
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:cloudwatch:EventTarget
    properties:
      arn: ${exampleStage.executionArn}/GET
      rule: ${exampleEventRule.id}
      httpTarget:
        queryStringParameters:
          Body: $.detail.body
        headerParameters:
          Env: Test
  exampleEventRule:
    type: aws:cloudwatch:EventRule
    name: example
  exampleDeployment:
    type: aws:apigateway:Deployment
    name: example
    properties:
      restApi: ${exampleAwsApiGatewayRestApi.id}
  exampleStage:
    type: aws:apigateway:Stage
    name: example
    properties:
      restApi: ${exampleAwsApiGatewayRestApi.id}
      deployment: ${exampleDeployment.id}

The httpTarget property configures the API call. The queryStringParameters map extracts fields from the event using JSONPath ($.detail.body) and passes them as query parameters. The headerParameters add static headers. The arn points to the API Gateway stage execution ARN with the HTTP method appended.

Forward events to another account’s event bus

Multi-account architectures centralize event processing by forwarding events across account boundaries.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const assumeRole = aws.iam.getPolicyDocument({
    statements: [{
        effect: "Allow",
        principals: [{
            type: "Service",
            identifiers: ["events.amazonaws.com"],
        }],
        actions: ["sts:AssumeRole"],
    }],
});
const eventBusInvokeRemoteEventBusRole = new aws.iam.Role("event_bus_invoke_remote_event_bus", {
    name: "event-bus-invoke-remote-event-bus",
    assumeRolePolicy: assumeRole.then(assumeRole => assumeRole.json),
});
const eventBusInvokeRemoteEventBus = aws.iam.getPolicyDocument({
    statements: [{
        effect: "Allow",
        actions: ["events:PutEvents"],
        resources: ["arn:aws:events:eu-west-1:1234567890:event-bus/My-Event-Bus"],
    }],
});
const eventBusInvokeRemoteEventBusPolicy = new aws.iam.Policy("event_bus_invoke_remote_event_bus", {
    name: "event_bus_invoke_remote_event_bus",
    policy: eventBusInvokeRemoteEventBus.then(eventBusInvokeRemoteEventBus => eventBusInvokeRemoteEventBus.json),
});
const eventBusInvokeRemoteEventBusRolePolicyAttachment = new aws.iam.RolePolicyAttachment("event_bus_invoke_remote_event_bus", {
    role: eventBusInvokeRemoteEventBusRole.name,
    policyArn: eventBusInvokeRemoteEventBusPolicy.arn,
});
const stopInstances = new aws.cloudwatch.EventRule("stop_instances", {
    name: "StopInstance",
    description: "Stop instances nightly",
    scheduleExpression: "cron(0 0 * * ? *)",
});
const stopInstancesEventTarget = new aws.cloudwatch.EventTarget("stop_instances", {
    targetId: "StopInstance",
    arn: "arn:aws:events:eu-west-1:1234567890:event-bus/My-Event-Bus",
    rule: stopInstances.name,
    roleArn: eventBusInvokeRemoteEventBusRole.arn,
});
import pulumi
import pulumi_aws as aws

assume_role = aws.iam.get_policy_document(statements=[{
    "effect": "Allow",
    "principals": [{
        "type": "Service",
        "identifiers": ["events.amazonaws.com"],
    }],
    "actions": ["sts:AssumeRole"],
}])
event_bus_invoke_remote_event_bus_role = aws.iam.Role("event_bus_invoke_remote_event_bus",
    name="event-bus-invoke-remote-event-bus",
    assume_role_policy=assume_role.json)
event_bus_invoke_remote_event_bus = aws.iam.get_policy_document(statements=[{
    "effect": "Allow",
    "actions": ["events:PutEvents"],
    "resources": ["arn:aws:events:eu-west-1:1234567890:event-bus/My-Event-Bus"],
}])
event_bus_invoke_remote_event_bus_policy = aws.iam.Policy("event_bus_invoke_remote_event_bus",
    name="event_bus_invoke_remote_event_bus",
    policy=event_bus_invoke_remote_event_bus.json)
event_bus_invoke_remote_event_bus_role_policy_attachment = aws.iam.RolePolicyAttachment("event_bus_invoke_remote_event_bus",
    role=event_bus_invoke_remote_event_bus_role.name,
    policy_arn=event_bus_invoke_remote_event_bus_policy.arn)
stop_instances = aws.cloudwatch.EventRule("stop_instances",
    name="StopInstance",
    description="Stop instances nightly",
    schedule_expression="cron(0 0 * * ? *)")
stop_instances_event_target = aws.cloudwatch.EventTarget("stop_instances",
    target_id="StopInstance",
    arn="arn:aws:events:eu-west-1:1234567890:event-bus/My-Event-Bus",
    rule=stop_instances.name,
    role_arn=event_bus_invoke_remote_event_bus_role.arn)
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cloudwatch"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		assumeRole, err := iam.GetPolicyDocument(ctx, &iam.GetPolicyDocumentArgs{
			Statements: []iam.GetPolicyDocumentStatement{
				{
					Effect: pulumi.StringRef("Allow"),
					Principals: []iam.GetPolicyDocumentStatementPrincipal{
						{
							Type: "Service",
							Identifiers: []string{
								"events.amazonaws.com",
							},
						},
					},
					Actions: []string{
						"sts:AssumeRole",
					},
				},
			},
		}, nil)
		if err != nil {
			return err
		}
		eventBusInvokeRemoteEventBusRole, err := iam.NewRole(ctx, "event_bus_invoke_remote_event_bus", &iam.RoleArgs{
			Name:             pulumi.String("event-bus-invoke-remote-event-bus"),
			AssumeRolePolicy: pulumi.String(assumeRole.Json),
		})
		if err != nil {
			return err
		}
		eventBusInvokeRemoteEventBus, err := iam.GetPolicyDocument(ctx, &iam.GetPolicyDocumentArgs{
			Statements: []iam.GetPolicyDocumentStatement{
				{
					Effect: pulumi.StringRef("Allow"),
					Actions: []string{
						"events:PutEvents",
					},
					Resources: []string{
						"arn:aws:events:eu-west-1:1234567890:event-bus/My-Event-Bus",
					},
				},
			},
		}, nil)
		if err != nil {
			return err
		}
		eventBusInvokeRemoteEventBusPolicy, err := iam.NewPolicy(ctx, "event_bus_invoke_remote_event_bus", &iam.PolicyArgs{
			Name:   pulumi.String("event_bus_invoke_remote_event_bus"),
			Policy: pulumi.String(eventBusInvokeRemoteEventBus.Json),
		})
		if err != nil {
			return err
		}
		_, err = iam.NewRolePolicyAttachment(ctx, "event_bus_invoke_remote_event_bus", &iam.RolePolicyAttachmentArgs{
			Role:      eventBusInvokeRemoteEventBusRole.Name,
			PolicyArn: eventBusInvokeRemoteEventBusPolicy.Arn,
		})
		if err != nil {
			return err
		}
		stopInstances, err := cloudwatch.NewEventRule(ctx, "stop_instances", &cloudwatch.EventRuleArgs{
			Name:               pulumi.String("StopInstance"),
			Description:        pulumi.String("Stop instances nightly"),
			ScheduleExpression: pulumi.String("cron(0 0 * * ? *)"),
		})
		if err != nil {
			return err
		}
		_, err = cloudwatch.NewEventTarget(ctx, "stop_instances", &cloudwatch.EventTargetArgs{
			TargetId: pulumi.String("StopInstance"),
			Arn:      pulumi.String("arn:aws:events:eu-west-1:1234567890:event-bus/My-Event-Bus"),
			Rule:     stopInstances.Name,
			RoleArn:  eventBusInvokeRemoteEventBusRole.Arn,
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var assumeRole = Aws.Iam.GetPolicyDocument.Invoke(new()
    {
        Statements = new[]
        {
            new Aws.Iam.Inputs.GetPolicyDocumentStatementInputArgs
            {
                Effect = "Allow",
                Principals = new[]
                {
                    new Aws.Iam.Inputs.GetPolicyDocumentStatementPrincipalInputArgs
                    {
                        Type = "Service",
                        Identifiers = new[]
                        {
                            "events.amazonaws.com",
                        },
                    },
                },
                Actions = new[]
                {
                    "sts:AssumeRole",
                },
            },
        },
    });

    var eventBusInvokeRemoteEventBusRole = new Aws.Iam.Role("event_bus_invoke_remote_event_bus", new()
    {
        Name = "event-bus-invoke-remote-event-bus",
        AssumeRolePolicy = assumeRole.Apply(getPolicyDocumentResult => getPolicyDocumentResult.Json),
    });

    var eventBusInvokeRemoteEventBus = Aws.Iam.GetPolicyDocument.Invoke(new()
    {
        Statements = new[]
        {
            new Aws.Iam.Inputs.GetPolicyDocumentStatementInputArgs
            {
                Effect = "Allow",
                Actions = new[]
                {
                    "events:PutEvents",
                },
                Resources = new[]
                {
                    "arn:aws:events:eu-west-1:1234567890:event-bus/My-Event-Bus",
                },
            },
        },
    });

    var eventBusInvokeRemoteEventBusPolicy = new Aws.Iam.Policy("event_bus_invoke_remote_event_bus", new()
    {
        Name = "event_bus_invoke_remote_event_bus",
        PolicyDocument = eventBusInvokeRemoteEventBus.Apply(getPolicyDocumentResult => getPolicyDocumentResult.Json),
    });

    var eventBusInvokeRemoteEventBusRolePolicyAttachment = new Aws.Iam.RolePolicyAttachment("event_bus_invoke_remote_event_bus", new()
    {
        Role = eventBusInvokeRemoteEventBusRole.Name,
        PolicyArn = eventBusInvokeRemoteEventBusPolicy.Arn,
    });

    var stopInstances = new Aws.CloudWatch.EventRule("stop_instances", new()
    {
        Name = "StopInstance",
        Description = "Stop instances nightly",
        ScheduleExpression = "cron(0 0 * * ? *)",
    });

    var stopInstancesEventTarget = new Aws.CloudWatch.EventTarget("stop_instances", new()
    {
        TargetId = "StopInstance",
        Arn = "arn:aws:events:eu-west-1:1234567890:event-bus/My-Event-Bus",
        Rule = stopInstances.Name,
        RoleArn = eventBusInvokeRemoteEventBusRole.Arn,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.iam.IamFunctions;
import com.pulumi.aws.iam.inputs.GetPolicyDocumentArgs;
import com.pulumi.aws.iam.Role;
import com.pulumi.aws.iam.RoleArgs;
import com.pulumi.aws.iam.Policy;
import com.pulumi.aws.iam.PolicyArgs;
import com.pulumi.aws.iam.RolePolicyAttachment;
import com.pulumi.aws.iam.RolePolicyAttachmentArgs;
import com.pulumi.aws.cloudwatch.EventRule;
import com.pulumi.aws.cloudwatch.EventRuleArgs;
import com.pulumi.aws.cloudwatch.EventTarget;
import com.pulumi.aws.cloudwatch.EventTargetArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        final var assumeRole = IamFunctions.getPolicyDocument(GetPolicyDocumentArgs.builder()
            .statements(GetPolicyDocumentStatementArgs.builder()
                .effect("Allow")
                .principals(GetPolicyDocumentStatementPrincipalArgs.builder()
                    .type("Service")
                    .identifiers("events.amazonaws.com")
                    .build())
                .actions("sts:AssumeRole")
                .build())
            .build());

        var eventBusInvokeRemoteEventBusRole = new Role("eventBusInvokeRemoteEventBusRole", RoleArgs.builder()
            .name("event-bus-invoke-remote-event-bus")
            .assumeRolePolicy(assumeRole.json())
            .build());

        final var eventBusInvokeRemoteEventBus = IamFunctions.getPolicyDocument(GetPolicyDocumentArgs.builder()
            .statements(GetPolicyDocumentStatementArgs.builder()
                .effect("Allow")
                .actions("events:PutEvents")
                .resources("arn:aws:events:eu-west-1:1234567890:event-bus/My-Event-Bus")
                .build())
            .build());

        var eventBusInvokeRemoteEventBusPolicy = new Policy("eventBusInvokeRemoteEventBusPolicy", PolicyArgs.builder()
            .name("event_bus_invoke_remote_event_bus")
            .policy(eventBusInvokeRemoteEventBus.json())
            .build());

        var eventBusInvokeRemoteEventBusRolePolicyAttachment = new RolePolicyAttachment("eventBusInvokeRemoteEventBusRolePolicyAttachment", RolePolicyAttachmentArgs.builder()
            .role(eventBusInvokeRemoteEventBusRole.name())
            .policyArn(eventBusInvokeRemoteEventBusPolicy.arn())
            .build());

        var stopInstances = new EventRule("stopInstances", EventRuleArgs.builder()
            .name("StopInstance")
            .description("Stop instances nightly")
            .scheduleExpression("cron(0 0 * * ? *)")
            .build());

        var stopInstancesEventTarget = new EventTarget("stopInstancesEventTarget", EventTargetArgs.builder()
            .targetId("StopInstance")
            .arn("arn:aws:events:eu-west-1:1234567890:event-bus/My-Event-Bus")
            .rule(stopInstances.name())
            .roleArn(eventBusInvokeRemoteEventBusRole.arn())
            .build());

    }
}
resources:
  eventBusInvokeRemoteEventBusRole:
    type: aws:iam:Role
    name: event_bus_invoke_remote_event_bus
    properties:
      name: event-bus-invoke-remote-event-bus
      assumeRolePolicy: ${assumeRole.json}
  eventBusInvokeRemoteEventBusPolicy:
    type: aws:iam:Policy
    name: event_bus_invoke_remote_event_bus
    properties:
      name: event_bus_invoke_remote_event_bus
      policy: ${eventBusInvokeRemoteEventBus.json}
  eventBusInvokeRemoteEventBusRolePolicyAttachment:
    type: aws:iam:RolePolicyAttachment
    name: event_bus_invoke_remote_event_bus
    properties:
      role: ${eventBusInvokeRemoteEventBusRole.name}
      policyArn: ${eventBusInvokeRemoteEventBusPolicy.arn}
  stopInstances:
    type: aws:cloudwatch:EventRule
    name: stop_instances
    properties:
      name: StopInstance
      description: Stop instances nightly
      scheduleExpression: cron(0 0 * * ? *)
  stopInstancesEventTarget:
    type: aws:cloudwatch:EventTarget
    name: stop_instances
    properties:
      targetId: StopInstance
      arn: arn:aws:events:eu-west-1:1234567890:event-bus/My-Event-Bus
      rule: ${stopInstances.name}
      roleArn: ${eventBusInvokeRemoteEventBusRole.arn}
variables:
  assumeRole:
    fn::invoke:
      function: aws:iam:getPolicyDocument
      arguments:
        statements:
          - effect: Allow
            principals:
              - type: Service
                identifiers:
                  - events.amazonaws.com
            actions:
              - sts:AssumeRole
  eventBusInvokeRemoteEventBus:
    fn::invoke:
      function: aws:iam:getPolicyDocument
      arguments:
        statements:
          - effect: Allow
            actions:
              - events:PutEvents
            resources:
              - arn:aws:events:eu-west-1:1234567890:event-bus/My-Event-Bus

The arn property references an event bus in another AWS account. The roleArn grants EventBridge permission to call PutEvents on the target bus. The target account must have a resource policy allowing PutEvents from the source account.

Transform event data into custom JSON payloads

Targets often need event data in a specific format rather than the raw event structure.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const exampleEventRule = new aws.cloudwatch.EventRule("example", {});
const example = new aws.cloudwatch.EventTarget("example", {
    arn: exampleAwsLambdaFunction.arn,
    rule: exampleEventRule.id,
    inputTransformer: {
        inputPaths: {
            instance: "$.detail.instance",
            status: "$.detail.status",
        },
        inputTemplate: `{
  \\"instance_id\\": <instance>,
  \\"instance_status\\": <status>
}
`,
    },
});
import pulumi
import pulumi_aws as aws

example_event_rule = aws.cloudwatch.EventRule("example")
example = aws.cloudwatch.EventTarget("example",
    arn=example_aws_lambda_function["arn"],
    rule=example_event_rule.id,
    input_transformer={
        "input_paths": {
            "instance": "$.detail.instance",
            "status": "$.detail.status",
        },
        "input_template": """{
  \"instance_id\": <instance>,
  \"instance_status\": <status>
}
""",
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cloudwatch"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		exampleEventRule, err := cloudwatch.NewEventRule(ctx, "example", nil)
		if err != nil {
			return err
		}
		_, err = cloudwatch.NewEventTarget(ctx, "example", &cloudwatch.EventTargetArgs{
			Arn:  pulumi.Any(exampleAwsLambdaFunction.Arn),
			Rule: exampleEventRule.ID(),
			InputTransformer: &cloudwatch.EventTargetInputTransformerArgs{
				InputPaths: pulumi.StringMap{
					"instance": pulumi.String("$.detail.instance"),
					"status":   pulumi.String("$.detail.status"),
				},
				InputTemplate: pulumi.String("{\n  \\\"instance_id\\\": <instance>,\n  \\\"instance_status\\\": <status>\n}\n"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var exampleEventRule = new Aws.CloudWatch.EventRule("example");

    var example = new Aws.CloudWatch.EventTarget("example", new()
    {
        Arn = exampleAwsLambdaFunction.Arn,
        Rule = exampleEventRule.Id,
        InputTransformer = new Aws.CloudWatch.Inputs.EventTargetInputTransformerArgs
        {
            InputPaths = 
            {
                { "instance", "$.detail.instance" },
                { "status", "$.detail.status" },
            },
            InputTemplate = @"{
  \""instance_id\"": <instance>,
  \""instance_status\"": <status>
}
",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.cloudwatch.EventRule;
import com.pulumi.aws.cloudwatch.EventTarget;
import com.pulumi.aws.cloudwatch.EventTargetArgs;
import com.pulumi.aws.cloudwatch.inputs.EventTargetInputTransformerArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var exampleEventRule = new EventRule("exampleEventRule");

        var example = new EventTarget("example", EventTargetArgs.builder()
            .arn(exampleAwsLambdaFunction.arn())
            .rule(exampleEventRule.id())
            .inputTransformer(EventTargetInputTransformerArgs.builder()
                .inputPaths(Map.ofEntries(
                    Map.entry("instance", "$.detail.instance"),
                    Map.entry("status", "$.detail.status")
                ))
                .inputTemplate("""
{
  \"instance_id\": <instance>,
  \"instance_status\": <status>
}
                """)
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:cloudwatch:EventTarget
    properties:
      arn: ${exampleAwsLambdaFunction.arn}
      rule: ${exampleEventRule.id}
      inputTransformer:
        inputPaths:
          instance: $.detail.instance
          status: $.detail.status
        inputTemplate: |
          {
            \"instance_id\": <instance>,
            \"instance_status\": <status>
          }          
  exampleEventRule:
    type: aws:cloudwatch:EventRule
    name: example

The inputTransformer extracts fields using JSONPath expressions in inputPaths, then constructs a new JSON object in inputTemplate. The template uses angle brackets to reference extracted values. This example pulls instance and status from the event and creates a simplified payload for the Lambda function.

Beyond these examples

These snippets focus on specific target-level features: target types (Kinesis, ECS, API Gateway, SSM, cross-account event buses), input transformation and container overrides, and tag-based targeting with runCommandTargets. They’re intentionally minimal rather than full event-driven applications.

The examples rely on pre-existing infrastructure such as EventBridge rules that match events, IAM roles with permissions for target services, and target resources (Kinesis streams, ECS clusters, API Gateway stages, SSM documents). They focus on configuring the target rather than provisioning everything around it.

To keep things focused, common target patterns are omitted, including:

  • Retry policies and dead letter queues (retryPolicy, deadLetterConfig)
  • Batch and SageMaker Pipeline targets
  • SQS and Redshift targets
  • Lambda permissions and SNS topic policies

These omissions are intentional: the goal is to illustrate how each target type is wired, not provide drop-in event processing modules. See the EventBridge Target resource reference for all available configuration options.

Let's configure AWS EventBridge Targets

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Permissions & IAM
What permissions do I need for Lambda or SNS targets?
You must set up explicit permissions using aws.lambda.Permission for Lambda functions or aws.sns.TopicPolicy for SNS topics to allow EventBridge to invoke them.
When is roleArn required?
roleArn is required when using ecsTarget or when the target is an EC2 instance, Kinesis data stream, Step Functions state machine, or Event Bus in a different account or region.
How do I target a cross-account Event Bus?
Set arn to the cross-account event bus ARN and provide a roleArn with events:PutEvents permission for the target event bus.
Target Configuration
What properties are immutable after creation?
rule, targetId, and eventBusName are immutable. Changing any of these forces resource replacement.
What's the difference between input, inputPath, and inputTransformer?
These are three mutually exclusive ways to pass data to targets. input sends static JSON, inputPath extracts part of the event using JSONPath, and inputTransformer transforms event data using templates. You can only use one.
What happens if I omit eventBusName?
The default event bus is used automatically.
What does forceDestroy do?
forceDestroy allows deletion of managed rules created by AWS. It defaults to false.
Target Types & Use Cases
How do I invoke an ECS task from an EventBridge rule?
Configure ecsTarget with taskDefinitionArn and taskCount, and provide a roleArn with permissions for iam:PassRole and ecs:RunTask.
Can I send events to an API Gateway endpoint?
Yes, use httpTarget with queryStringParameters and headerParameters to configure the API Gateway invocation.
How do I send events to a CloudWatch Log Group?
Set arn to the log group ARN and create a CloudWatch log resource policy allowing events.amazonaws.com to perform logs:CreateLogStream and logs:PutLogEvents.
Can I invoke AppSync GraphQL mutations from EventBridge?
Yes, use appsyncTarget with graphqlOperation and provide a roleArn with appsync:GraphQL permission.
Input Transformation
How do I transform event data before sending to a target?
Use inputTransformer with inputPaths to extract event fields (e.g., {"instance": "$.detail.instance"}) and inputTemplate to format the output as JSON or a simple string.

Using a different cloud?

Explore integration guides for other cloud providers: