Configure AWS Glue Triggers

The aws:glue/trigger:Trigger resource, part of the Pulumi AWS provider, defines when and how Glue jobs and crawlers execute: manual invocation, scheduled runs, or conditional orchestration based on job or crawler state. This guide focuses on three capabilities: manual, scheduled, and conditional trigger types; job-to-job and crawler-to-job orchestration; and predicate-based execution control.

Triggers reference existing Glue jobs and crawlers by name. They orchestrate execution but don’t create the jobs or crawlers themselves. The examples are intentionally small. Combine them with your own Glue jobs, crawlers, and workflow requirements.

Start jobs manually with on-demand triggers

Data pipelines often need manual control points where operators can initiate processing when data is ready or when business conditions require it.

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

const example = new aws.glue.Trigger("example", {
    name: "example",
    type: "ON_DEMAND",
    actions: [{
        jobName: exampleAwsGlueJob.name,
    }],
});
import pulumi
import pulumi_aws as aws

example = aws.glue.Trigger("example",
    name="example",
    type="ON_DEMAND",
    actions=[{
        "job_name": example_aws_glue_job["name"],
    }])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := glue.NewTrigger(ctx, "example", &glue.TriggerArgs{
			Name: pulumi.String("example"),
			Type: pulumi.String("ON_DEMAND"),
			Actions: glue.TriggerActionArray{
				&glue.TriggerActionArgs{
					JobName: pulumi.Any(exampleAwsGlueJob.Name),
				},
			},
		})
		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 example = new Aws.Glue.Trigger("example", new()
    {
        Name = "example",
        Type = "ON_DEMAND",
        Actions = new[]
        {
            new Aws.Glue.Inputs.TriggerActionArgs
            {
                JobName = exampleAwsGlueJob.Name,
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.glue.Trigger;
import com.pulumi.aws.glue.TriggerArgs;
import com.pulumi.aws.glue.inputs.TriggerActionArgs;
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 example = new Trigger("example", TriggerArgs.builder()
            .name("example")
            .type("ON_DEMAND")
            .actions(TriggerActionArgs.builder()
                .jobName(exampleAwsGlueJob.name())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:glue:Trigger
    properties:
      name: example
      type: ON_DEMAND
      actions:
        - jobName: ${exampleAwsGlueJob.name}

The type property set to ON_DEMAND creates a trigger that fires only when explicitly invoked via the AWS console, CLI, or API. The actions property specifies which job to run. This trigger type has no schedule or predicate; it waits for manual activation.

Run jobs on a fixed schedule with cron

Batch processing workloads typically run at predictable intervals, such as nightly data loads or hourly aggregations.

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

const example = new aws.glue.Trigger("example", {
    name: "example",
    schedule: "cron(15 12 * * ? *)",
    type: "SCHEDULED",
    actions: [{
        jobName: exampleAwsGlueJob.name,
    }],
});
import pulumi
import pulumi_aws as aws

example = aws.glue.Trigger("example",
    name="example",
    schedule="cron(15 12 * * ? *)",
    type="SCHEDULED",
    actions=[{
        "job_name": example_aws_glue_job["name"],
    }])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := glue.NewTrigger(ctx, "example", &glue.TriggerArgs{
			Name:     pulumi.String("example"),
			Schedule: pulumi.String("cron(15 12 * * ? *)"),
			Type:     pulumi.String("SCHEDULED"),
			Actions: glue.TriggerActionArray{
				&glue.TriggerActionArgs{
					JobName: pulumi.Any(exampleAwsGlueJob.Name),
				},
			},
		})
		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 example = new Aws.Glue.Trigger("example", new()
    {
        Name = "example",
        Schedule = "cron(15 12 * * ? *)",
        Type = "SCHEDULED",
        Actions = new[]
        {
            new Aws.Glue.Inputs.TriggerActionArgs
            {
                JobName = exampleAwsGlueJob.Name,
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.glue.Trigger;
import com.pulumi.aws.glue.TriggerArgs;
import com.pulumi.aws.glue.inputs.TriggerActionArgs;
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 example = new Trigger("example", TriggerArgs.builder()
            .name("example")
            .schedule("cron(15 12 * * ? *)")
            .type("SCHEDULED")
            .actions(TriggerActionArgs.builder()
                .jobName(exampleAwsGlueJob.name())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:glue:Trigger
    properties:
      name: example
      schedule: cron(15 12 * * ? *)
      type: SCHEDULED
      actions:
        - jobName: ${exampleAwsGlueJob.name}

The schedule property accepts cron expressions that define when the trigger fires. The type property set to SCHEDULED tells Glue to evaluate the cron expression and start the job automatically at matching times. This example runs daily at 12:15 PM UTC.

Chain jobs based on completion state

ETL workflows often require sequential processing where downstream jobs wait for upstream jobs to complete successfully before starting.

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

const example = new aws.glue.Trigger("example", {
    name: "example",
    type: "CONDITIONAL",
    actions: [{
        jobName: example1.name,
    }],
    predicate: {
        conditions: [{
            jobName: example2.name,
            state: "SUCCEEDED",
        }],
    },
});
import pulumi
import pulumi_aws as aws

example = aws.glue.Trigger("example",
    name="example",
    type="CONDITIONAL",
    actions=[{
        "job_name": example1["name"],
    }],
    predicate={
        "conditions": [{
            "job_name": example2["name"],
            "state": "SUCCEEDED",
        }],
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := glue.NewTrigger(ctx, "example", &glue.TriggerArgs{
			Name: pulumi.String("example"),
			Type: pulumi.String("CONDITIONAL"),
			Actions: glue.TriggerActionArray{
				&glue.TriggerActionArgs{
					JobName: pulumi.Any(example1.Name),
				},
			},
			Predicate: &glue.TriggerPredicateArgs{
				Conditions: glue.TriggerPredicateConditionArray{
					&glue.TriggerPredicateConditionArgs{
						JobName: pulumi.Any(example2.Name),
						State:   pulumi.String("SUCCEEDED"),
					},
				},
			},
		})
		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 example = new Aws.Glue.Trigger("example", new()
    {
        Name = "example",
        Type = "CONDITIONAL",
        Actions = new[]
        {
            new Aws.Glue.Inputs.TriggerActionArgs
            {
                JobName = example1.Name,
            },
        },
        Predicate = new Aws.Glue.Inputs.TriggerPredicateArgs
        {
            Conditions = new[]
            {
                new Aws.Glue.Inputs.TriggerPredicateConditionArgs
                {
                    JobName = example2.Name,
                    State = "SUCCEEDED",
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.glue.Trigger;
import com.pulumi.aws.glue.TriggerArgs;
import com.pulumi.aws.glue.inputs.TriggerActionArgs;
import com.pulumi.aws.glue.inputs.TriggerPredicateArgs;
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 example = new Trigger("example", TriggerArgs.builder()
            .name("example")
            .type("CONDITIONAL")
            .actions(TriggerActionArgs.builder()
                .jobName(example1.name())
                .build())
            .predicate(TriggerPredicateArgs.builder()
                .conditions(TriggerPredicateConditionArgs.builder()
                    .jobName(example2.name())
                    .state("SUCCEEDED")
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:glue:Trigger
    properties:
      name: example
      type: CONDITIONAL
      actions:
        - jobName: ${example1.name}
      predicate:
        conditions:
          - jobName: ${example2.name}
            state: SUCCEEDED

The predicate property defines conditions that must be met before the trigger fires. Each condition specifies a job name and the state it must reach (SUCCEEDED, FAILED, STOPPED, or TIMEOUT). When all conditions are satisfied, the trigger starts the job listed in actions. This creates job dependencies and execution order.

Trigger crawlers after job completion

After ETL jobs write data to S3 or databases, crawlers can automatically update the Data Catalog with new schema information.

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

const example = new aws.glue.Trigger("example", {
    name: "example",
    type: "CONDITIONAL",
    actions: [{
        crawlerName: example1.name,
    }],
    predicate: {
        conditions: [{
            jobName: example2.name,
            state: "SUCCEEDED",
        }],
    },
});
import pulumi
import pulumi_aws as aws

example = aws.glue.Trigger("example",
    name="example",
    type="CONDITIONAL",
    actions=[{
        "crawler_name": example1["name"],
    }],
    predicate={
        "conditions": [{
            "job_name": example2["name"],
            "state": "SUCCEEDED",
        }],
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := glue.NewTrigger(ctx, "example", &glue.TriggerArgs{
			Name: pulumi.String("example"),
			Type: pulumi.String("CONDITIONAL"),
			Actions: glue.TriggerActionArray{
				&glue.TriggerActionArgs{
					CrawlerName: pulumi.Any(example1.Name),
				},
			},
			Predicate: &glue.TriggerPredicateArgs{
				Conditions: glue.TriggerPredicateConditionArray{
					&glue.TriggerPredicateConditionArgs{
						JobName: pulumi.Any(example2.Name),
						State:   pulumi.String("SUCCEEDED"),
					},
				},
			},
		})
		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 example = new Aws.Glue.Trigger("example", new()
    {
        Name = "example",
        Type = "CONDITIONAL",
        Actions = new[]
        {
            new Aws.Glue.Inputs.TriggerActionArgs
            {
                CrawlerName = example1.Name,
            },
        },
        Predicate = new Aws.Glue.Inputs.TriggerPredicateArgs
        {
            Conditions = new[]
            {
                new Aws.Glue.Inputs.TriggerPredicateConditionArgs
                {
                    JobName = example2.Name,
                    State = "SUCCEEDED",
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.glue.Trigger;
import com.pulumi.aws.glue.TriggerArgs;
import com.pulumi.aws.glue.inputs.TriggerActionArgs;
import com.pulumi.aws.glue.inputs.TriggerPredicateArgs;
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 example = new Trigger("example", TriggerArgs.builder()
            .name("example")
            .type("CONDITIONAL")
            .actions(TriggerActionArgs.builder()
                .crawlerName(example1.name())
                .build())
            .predicate(TriggerPredicateArgs.builder()
                .conditions(TriggerPredicateConditionArgs.builder()
                    .jobName(example2.name())
                    .state("SUCCEEDED")
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:glue:Trigger
    properties:
      name: example
      type: CONDITIONAL
      actions:
        - crawlerName: ${example1.name}
      predicate:
        conditions:
          - jobName: ${example2.name}
            state: SUCCEEDED

Instead of starting a job, the actions property can specify a crawlerName to run. The predicate still watches job completion, but the trigger starts a crawler rather than another job. This pattern keeps catalog metadata synchronized with newly processed data.

Start jobs after crawler discovery

Some workflows begin with crawlers discovering new data, then trigger jobs to process what was found.

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

const example = new aws.glue.Trigger("example", {
    name: "example",
    type: "CONDITIONAL",
    actions: [{
        jobName: example1.name,
    }],
    predicate: {
        conditions: [{
            crawlerName: example2.name,
            crawlState: "SUCCEEDED",
        }],
    },
});
import pulumi
import pulumi_aws as aws

example = aws.glue.Trigger("example",
    name="example",
    type="CONDITIONAL",
    actions=[{
        "job_name": example1["name"],
    }],
    predicate={
        "conditions": [{
            "crawler_name": example2["name"],
            "crawl_state": "SUCCEEDED",
        }],
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := glue.NewTrigger(ctx, "example", &glue.TriggerArgs{
			Name: pulumi.String("example"),
			Type: pulumi.String("CONDITIONAL"),
			Actions: glue.TriggerActionArray{
				&glue.TriggerActionArgs{
					JobName: pulumi.Any(example1.Name),
				},
			},
			Predicate: &glue.TriggerPredicateArgs{
				Conditions: glue.TriggerPredicateConditionArray{
					&glue.TriggerPredicateConditionArgs{
						CrawlerName: pulumi.Any(example2.Name),
						CrawlState:  pulumi.String("SUCCEEDED"),
					},
				},
			},
		})
		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 example = new Aws.Glue.Trigger("example", new()
    {
        Name = "example",
        Type = "CONDITIONAL",
        Actions = new[]
        {
            new Aws.Glue.Inputs.TriggerActionArgs
            {
                JobName = example1.Name,
            },
        },
        Predicate = new Aws.Glue.Inputs.TriggerPredicateArgs
        {
            Conditions = new[]
            {
                new Aws.Glue.Inputs.TriggerPredicateConditionArgs
                {
                    CrawlerName = example2.Name,
                    CrawlState = "SUCCEEDED",
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.glue.Trigger;
import com.pulumi.aws.glue.TriggerArgs;
import com.pulumi.aws.glue.inputs.TriggerActionArgs;
import com.pulumi.aws.glue.inputs.TriggerPredicateArgs;
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 example = new Trigger("example", TriggerArgs.builder()
            .name("example")
            .type("CONDITIONAL")
            .actions(TriggerActionArgs.builder()
                .jobName(example1.name())
                .build())
            .predicate(TriggerPredicateArgs.builder()
                .conditions(TriggerPredicateConditionArgs.builder()
                    .crawlerName(example2.name())
                    .crawlState("SUCCEEDED")
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:glue:Trigger
    properties:
      name: example
      type: CONDITIONAL
      actions:
        - jobName: ${example1.name}
      predicate:
        conditions:
          - crawlerName: ${example2.name}
            crawlState: SUCCEEDED

The conditions property can watch crawler state using crawlerName and crawlState instead of jobName and state. When the crawler completes successfully, the trigger starts the job. This pattern enables discovery-driven processing where jobs react to newly cataloged data.

Beyond these examples

These snippets focus on specific trigger features: trigger types (on-demand, scheduled, conditional), job and crawler orchestration, and predicate-based execution control. They’re intentionally minimal rather than full workflow definitions.

The examples reference pre-existing infrastructure such as Glue jobs and crawlers. They focus on trigger configuration rather than provisioning the jobs and crawlers themselves.

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

  • EventBridge event triggers (eventBatchingConditions)
  • Workflow association (workflowName)
  • Trigger state management (enabled, startOnCreation)
  • Complex predicates with multiple conditions or logical operators

These omissions are intentional: the goal is to illustrate how each trigger type is wired, not provide drop-in workflow modules. See the Glue Trigger resource reference for all available configuration options.

Let's configure AWS Glue Triggers

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Trigger Types & Configuration
What are the trigger types and when should I use each?
Glue supports four trigger types: CONDITIONAL (fires when conditions are met), EVENT (fires on EventBridge events), ON_DEMAND (manual execution), and SCHEDULED (fires on a cron schedule). Use CONDITIONAL for job dependencies, SCHEDULED for time-based automation, ON_DEMAND for manual workflows, and EVENT for event-driven architectures.
When is the predicate property required?
The predicate property is required when the trigger type is CONDITIONAL. It specifies the conditions that must be met before the trigger fires.
How do I schedule a trigger to run at specific times?
Set type to SCHEDULED and provide a cron expression in the schedule property, such as cron(15 12 * * ? *) for daily execution at 12:15 PM UTC.
Actions & Conditions
Can I use triggers with both Glue jobs and crawlers?
Yes. Actions can specify either jobName to trigger a job or crawlerName to trigger a crawler. Similarly, predicate conditions can monitor either job completion (jobName with state) or crawler completion (crawlerName with crawlState).
Workflows & Dependencies
How do I set up a workflow with multiple triggers?
Associate triggers to a workflow using workflowName. Every workflow DAG requires a starting trigger (ON_DEMAND or SCHEDULED type) and can contain multiple additional CONDITIONAL triggers for dependencies.
Activation & Startup
What's the difference between enabled and startOnCreation?
enabled controls whether the trigger is active (defaults to true). startOnCreation determines if SCHEDULED and CONDITIONAL triggers start immediately upon creation, rather than waiting for their first scheduled time or condition.
Can I automatically start an ON_DEMAND trigger when I create it?
No. Setting startOnCreation to true is not supported for ON_DEMAND triggers. This property only works with SCHEDULED and CONDITIONAL types.
Limitations & Immutability
What properties can't I change after creating a trigger?
The name, type, and workflowName properties are immutable. Changing any of these requires recreating the trigger.

Using a different cloud?

Explore analytics guides for other cloud providers: