Configure AWS DataSync Tasks

The aws:datasync/task:Task resource, part of the Pulumi AWS provider, defines a DataSync task configuration that specifies how files should be synchronized between two locations. This guide focuses on four capabilities: basic task setup with bandwidth control, scheduled execution, file filtering, and enhanced mode for S3-to-S3 transfers.

DataSync tasks connect pre-existing source and destination locations. The task resource defines the sync configuration; actual file transfers happen when you execute the task outside of Pulumi. The examples are intentionally small. Combine them with your own DataSync locations and execution logic.

Create a basic task between two locations

Most deployments start by defining a task that connects a source to a destination. The task is a reusable configuration; you execute it separately to actually transfer files.

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

const example = new aws.datasync.Task("example", {
    destinationLocationArn: destination.arn,
    name: "example",
    sourceLocationArn: source.arn,
    options: {
        bytesPerSecond: -1,
    },
});
import pulumi
import pulumi_aws as aws

example = aws.datasync.Task("example",
    destination_location_arn=destination["arn"],
    name="example",
    source_location_arn=source["arn"],
    options={
        "bytes_per_second": -1,
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := datasync.NewTask(ctx, "example", &datasync.TaskArgs{
			DestinationLocationArn: pulumi.Any(destination.Arn),
			Name:                   pulumi.String("example"),
			SourceLocationArn:      pulumi.Any(source.Arn),
			Options: &datasync.TaskOptionsArgs{
				BytesPerSecond: pulumi.Int(-1),
			},
		})
		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.DataSync.Task("example", new()
    {
        DestinationLocationArn = destination.Arn,
        Name = "example",
        SourceLocationArn = source.Arn,
        Options = new Aws.DataSync.Inputs.TaskOptionsArgs
        {
            BytesPerSecond = -1,
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.datasync.Task;
import com.pulumi.aws.datasync.TaskArgs;
import com.pulumi.aws.datasync.inputs.TaskOptionsArgs;
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 Task("example", TaskArgs.builder()
            .destinationLocationArn(destination.arn())
            .name("example")
            .sourceLocationArn(source.arn())
            .options(TaskOptionsArgs.builder()
                .bytesPerSecond(-1)
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:datasync:Task
    properties:
      destinationLocationArn: ${destination.arn}
      name: example
      sourceLocationArn: ${source.arn}
      options:
        bytesPerSecond: -1

The sourceLocationArn and destinationLocationArn connect your task to existing DataSync locations. The options block controls transfer behavior; setting bytesPerSecond to -1 removes bandwidth throttling, allowing maximum throughput.

Schedule automatic transfers with cron expressions

Teams running regular migrations or backups schedule tasks to run automatically at specific times.

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

const example = new aws.datasync.Task("example", {
    destinationLocationArn: destination.arn,
    name: "example",
    sourceLocationArn: source.arn,
    schedule: {
        scheduleExpression: "cron(0 12 ? * SUN,WED *)",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.datasync.Task("example",
    destination_location_arn=destination["arn"],
    name="example",
    source_location_arn=source["arn"],
    schedule={
        "schedule_expression": "cron(0 12 ? * SUN,WED *)",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := datasync.NewTask(ctx, "example", &datasync.TaskArgs{
			DestinationLocationArn: pulumi.Any(destination.Arn),
			Name:                   pulumi.String("example"),
			SourceLocationArn:      pulumi.Any(source.Arn),
			Schedule: &datasync.TaskScheduleArgs{
				ScheduleExpression: pulumi.String("cron(0 12 ? * SUN,WED *)"),
			},
		})
		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.DataSync.Task("example", new()
    {
        DestinationLocationArn = destination.Arn,
        Name = "example",
        SourceLocationArn = source.Arn,
        Schedule = new Aws.DataSync.Inputs.TaskScheduleArgs
        {
            ScheduleExpression = "cron(0 12 ? * SUN,WED *)",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.datasync.Task;
import com.pulumi.aws.datasync.TaskArgs;
import com.pulumi.aws.datasync.inputs.TaskScheduleArgs;
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 Task("example", TaskArgs.builder()
            .destinationLocationArn(destination.arn())
            .name("example")
            .sourceLocationArn(source.arn())
            .schedule(TaskScheduleArgs.builder()
                .scheduleExpression("cron(0 12 ? * SUN,WED *)")
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:datasync:Task
    properties:
      destinationLocationArn: ${destination.arn}
      name: example
      sourceLocationArn: ${source.arn}
      schedule:
        scheduleExpression: cron(0 12 ? * SUN,WED *)

The schedule block defines when DataSync executes the task. The scheduleExpression uses cron syntax; this example runs every Sunday and Wednesday at noon UTC. DataSync handles execution automatically once scheduled.

Filter files with include and exclude patterns

Large datasets often contain files that shouldn’t be transferred. Pattern-based filtering controls which files participate in the sync.

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

const example = new aws.datasync.Task("example", {
    destinationLocationArn: destination.arn,
    name: "example",
    sourceLocationArn: source.arn,
    excludes: {
        filterType: "SIMPLE_PATTERN",
        value: "/folder1|/folder2",
    },
    includes: {
        filterType: "SIMPLE_PATTERN",
        value: "/folder1|/folder2",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.datasync.Task("example",
    destination_location_arn=destination["arn"],
    name="example",
    source_location_arn=source["arn"],
    excludes={
        "filter_type": "SIMPLE_PATTERN",
        "value": "/folder1|/folder2",
    },
    includes={
        "filter_type": "SIMPLE_PATTERN",
        "value": "/folder1|/folder2",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := datasync.NewTask(ctx, "example", &datasync.TaskArgs{
			DestinationLocationArn: pulumi.Any(destination.Arn),
			Name:                   pulumi.String("example"),
			SourceLocationArn:      pulumi.Any(source.Arn),
			Excludes: &datasync.TaskExcludesArgs{
				FilterType: pulumi.String("SIMPLE_PATTERN"),
				Value:      pulumi.String("/folder1|/folder2"),
			},
			Includes: &datasync.TaskIncludesArgs{
				FilterType: pulumi.String("SIMPLE_PATTERN"),
				Value:      pulumi.String("/folder1|/folder2"),
			},
		})
		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.DataSync.Task("example", new()
    {
        DestinationLocationArn = destination.Arn,
        Name = "example",
        SourceLocationArn = source.Arn,
        Excludes = new Aws.DataSync.Inputs.TaskExcludesArgs
        {
            FilterType = "SIMPLE_PATTERN",
            Value = "/folder1|/folder2",
        },
        Includes = new Aws.DataSync.Inputs.TaskIncludesArgs
        {
            FilterType = "SIMPLE_PATTERN",
            Value = "/folder1|/folder2",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.datasync.Task;
import com.pulumi.aws.datasync.TaskArgs;
import com.pulumi.aws.datasync.inputs.TaskExcludesArgs;
import com.pulumi.aws.datasync.inputs.TaskIncludesArgs;
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 Task("example", TaskArgs.builder()
            .destinationLocationArn(destination.arn())
            .name("example")
            .sourceLocationArn(source.arn())
            .excludes(TaskExcludesArgs.builder()
                .filterType("SIMPLE_PATTERN")
                .value("/folder1|/folder2")
                .build())
            .includes(TaskIncludesArgs.builder()
                .filterType("SIMPLE_PATTERN")
                .value("/folder1|/folder2")
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:datasync:Task
    properties:
      destinationLocationArn: ${destination.arn}
      name: example
      sourceLocationArn: ${source.arn}
      excludes:
        filterType: SIMPLE_PATTERN
        value: /folder1|/folder2
      includes:
        filterType: SIMPLE_PATTERN
        value: /folder1|/folder2

The excludes and includes blocks use SIMPLE_PATTERN filtering to match paths. The value property accepts pipe-separated patterns; this example targets specific folders. DataSync evaluates filters before transferring files.

Enable enhanced mode for S3-to-S3 transfers

Transfers between S3 locations can use enhanced mode for higher performance and better monitoring when moving large object counts.

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

const example = new aws.datasync.Task("example", {
    destinationLocationArn: destination.arn,
    name: "example",
    sourceLocationArn: source.arn,
    taskMode: "ENHANCED",
    options: {
        gid: "NONE",
        posixPermissions: "NONE",
        uid: "NONE",
        verifyMode: "ONLY_FILES_TRANSFERRED",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.datasync.Task("example",
    destination_location_arn=destination["arn"],
    name="example",
    source_location_arn=source["arn"],
    task_mode="ENHANCED",
    options={
        "gid": "NONE",
        "posix_permissions": "NONE",
        "uid": "NONE",
        "verify_mode": "ONLY_FILES_TRANSFERRED",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := datasync.NewTask(ctx, "example", &datasync.TaskArgs{
			DestinationLocationArn: pulumi.Any(destination.Arn),
			Name:                   pulumi.String("example"),
			SourceLocationArn:      pulumi.Any(source.Arn),
			TaskMode:               pulumi.String("ENHANCED"),
			Options: &datasync.TaskOptionsArgs{
				Gid:              pulumi.String("NONE"),
				PosixPermissions: pulumi.String("NONE"),
				Uid:              pulumi.String("NONE"),
				VerifyMode:       pulumi.String("ONLY_FILES_TRANSFERRED"),
			},
		})
		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.DataSync.Task("example", new()
    {
        DestinationLocationArn = destination.Arn,
        Name = "example",
        SourceLocationArn = source.Arn,
        TaskMode = "ENHANCED",
        Options = new Aws.DataSync.Inputs.TaskOptionsArgs
        {
            Gid = "NONE",
            PosixPermissions = "NONE",
            Uid = "NONE",
            VerifyMode = "ONLY_FILES_TRANSFERRED",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.datasync.Task;
import com.pulumi.aws.datasync.TaskArgs;
import com.pulumi.aws.datasync.inputs.TaskOptionsArgs;
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 Task("example", TaskArgs.builder()
            .destinationLocationArn(destination.arn())
            .name("example")
            .sourceLocationArn(source.arn())
            .taskMode("ENHANCED")
            .options(TaskOptionsArgs.builder()
                .gid("NONE")
                .posixPermissions("NONE")
                .uid("NONE")
                .verifyMode("ONLY_FILES_TRANSFERRED")
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:datasync:Task
    properties:
      destinationLocationArn: ${destination.arn}
      name: example
      sourceLocationArn: ${source.arn}
      taskMode: ENHANCED
      options:
        gid: NONE
        posixPermissions: NONE
        uid: NONE
        verifyMode: ONLY_FILES_TRANSFERRED

The taskMode property switches to ENHANCED, which is only available for S3-to-S3 transfers. Enhanced mode provides better metrics and logging. The options block configures how DataSync handles POSIX metadata; setting gid, uid, and posixPermissions to NONE skips metadata preservation. The verifyMode property controls data integrity checks.

Beyond these examples

These snippets focus on specific task-level features: basic task configuration and bandwidth control, scheduled execution with cron expressions, and file filtering with include/exclude patterns. They’re intentionally minimal rather than full data migration solutions.

The examples reference pre-existing infrastructure such as DataSync source and destination locations (S3, EFS, FSx, NFS, SMB), and CloudWatch Log Groups if logging is configured. They focus on task configuration rather than provisioning the locations themselves.

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

  • CloudWatch logging configuration (cloudwatchLogGroupArn)
  • Task report generation (taskReportConfig)
  • Resource tagging (tags)
  • Task execution (happens outside this resource)

These omissions are intentional: the goal is to illustrate how each task feature is wired, not provide drop-in migration modules. See the DataSync Task resource reference for all available configuration options.

Let's configure AWS DataSync Tasks

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Task Execution & Lifecycle
Does creating a DataSync task automatically start syncing files?
No, creating a task only configures the synchronization. You must start task executions separately outside of this resource.
What properties can't I change after creating a task?
Three properties are immutable: destinationLocationArn, sourceLocationArn, and taskMode. Changing any of these requires recreating the task.
Task Modes & Performance
What's the difference between BASIC and ENHANCED task modes?
BASIC (default) transfers files between AWS storage and on-premises, edge, or other cloud storage. ENHANCED transfers virtually unlimited objects with enhanced metrics, more detailed logs, and higher performance, but is currently only available for S3-to-S3 transfers.
How do I control bandwidth usage during transfers?
Set options.bytesPerSecond to limit bandwidth. Use -1 for unlimited bandwidth.
What options should I use with Enhanced mode?
Enhanced mode typically uses gid: NONE, uid: NONE, posixPermissions: NONE, and verifyMode: ONLY_FILES_TRANSFERRED as shown in the example.
Scheduling & Automation
How do I schedule automatic file syncs?
Configure the schedule block with a scheduleExpression using cron syntax, such as cron(0 12 ? * SUN,WED *) for syncs at noon on Sundays and Wednesdays.
File Filtering
How do I filter which files get synced?
Use includes or excludes blocks with filterType: SIMPLE_PATTERN and pipe-delimited patterns in the value field, such as /folder1|/folder2.

Using a different cloud?

Explore storage guides for other cloud providers: