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: manually, on schedules, or based on completion of other jobs and crawlers. This guide focuses on three capabilities: manual execution with on-demand triggers, scheduled execution with cron expressions, and conditional execution based on job and crawler state.

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

Start jobs manually with on-demand triggers

ETL pipelines often need manual control for testing, backfills, or ad-hoc processing without waiting for schedules or conditions.

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 you can invoke through the console, CLI, or API. The actions array specifies which job to run. This trigger has no schedule or predicate; it fires only when explicitly invoked.

Run jobs on a cron schedule

Most data pipelines run on fixed schedules, processing data at regular intervals throughout the day or week.

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 must be SCHEDULED. This trigger runs the specified job at 12:15 PM UTC daily without requiring manual invocation or upstream job completion.

Chain jobs based on completion state

Complex pipelines often require jobs to run in sequence, with downstream jobs waiting for upstream jobs to complete successfully.

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). The type property must be CONDITIONAL. When the upstream job succeeds, this trigger automatically starts the downstream job.

Start crawlers after job completion

After ETL jobs write data to S3 or databases, crawlers need to run to update the Data Catalog with new schemas and partitions.

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

The actions array can specify a crawlerName instead of a jobName. This trigger waits for a job to succeed, then starts a crawler to update the catalog. The predicate still references a job condition, but the action targets a crawler.

Run jobs after crawler discovery

Some pipelines start with crawlers that discover 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 predicate can reference crawler completion using crawlerName and crawlState instead of jobName and state. Valid crawler states are SUCCEEDED, FAILED, and CANCELLED. This trigger starts a job after the crawler successfully updates the catalog.

Beyond these examples

These snippets focus on specific trigger features: manual, scheduled, and conditional execution, and job and crawler orchestration. They’re intentionally minimal rather than full pipeline definitions.

The examples reference pre-existing infrastructure such as Glue jobs and crawlers that triggers will start. 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)
  • Multiple conditions with logical operators (predicate.logical)

These omissions are intentional: the goal is to illustrate how each trigger type is wired, not provide drop-in orchestration 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 trigger types are available in AWS Glue?
Four types: CONDITIONAL (fires based on job/crawler conditions), EVENT (responds to EventBridge events), ON_DEMAND (manual execution), and SCHEDULED (cron-based timing).
What's a CONDITIONAL trigger and when do I need it?
A CONDITIONAL trigger fires when specified conditions are met, such as a job succeeding. You must configure a predicate with conditions when using this type.
How do I schedule a trigger to run at specific times?
Use type: "SCHEDULED" with a cron expression in the schedule property, like "cron(15 12 * * ? *)" for daily at 12:15 PM UTC.
Scheduling & Activation
Why isn't my trigger starting automatically after creation?
Check two settings: enabled (defaults to true) controls whether the trigger is active, and startOnCreation starts SCHEDULED and CONDITIONAL triggers immediately. Note that startOnCreation isn’t supported for ON_DEMAND triggers.
Can I use startOnCreation with ON_DEMAND triggers?
No, startOnCreation is only supported for SCHEDULED and CONDITIONAL triggers. ON_DEMAND triggers are executed manually.
Actions & Conditions
Can triggers execute both jobs and crawlers?
Yes, triggers can execute both. Actions can specify jobName or crawlerName, and conditions can check the state of either jobs or crawlers.
What's the difference between actions and predicates?
Actions define what executes when the trigger fires (jobs or crawlers). Predicates define the conditions that must be met for CONDITIONAL triggers to fire (like a job succeeding).
Workflows & Dependencies
How do I set up a workflow with multiple triggers?
Associate triggers using workflowName. Every workflow DAG requires a starting trigger (ON_DEMAND or SCHEDULED type) and can include multiple CONDITIONAL triggers for dependencies.
Can I change which workflow a trigger belongs to?
No, workflowName is immutable. Changing it requires recreating the trigger.
Immutability & Updates
What properties can't I change after creating a trigger?
Three properties are immutable: name, type, and workflowName. Changing any of these requires replacing the trigger.

Using a different cloud?

Explore analytics guides for other cloud providers: