Create AWS QuickSight Data Sets

The aws:quicksight/dataSet:DataSet resource, part of the Pulumi AWS provider, defines a QuickSight dataset: its data source connections, column schema, and access controls. This guide focuses on three capabilities: S3 data import into SPICE, column and row-level security, and field organization and user permissions.

Datasets reference QuickSight data sources (which connect to S3, RDS, Redshift, or other sources) and grant permissions to QuickSight users or groups. The examples are intentionally small. Combine them with your own data sources, user management, and logical table transformations.

Load data from S3 into SPICE

Most QuickSight deployments start by defining a dataset that imports data from S3 into SPICE (QuickSight’s in-memory engine) for fast query performance.

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

const example = new aws.quicksight.DataSet("example", {
    dataSetId: "example-id",
    name: "example-name",
    importMode: "SPICE",
    physicalTableMaps: [{
        physicalTableMapId: "example-id",
        s3Source: {
            dataSourceArn: exampleAwsQuicksightDataSource.arn,
            inputColumns: [{
                name: "Column1",
                type: "STRING",
            }],
            uploadSettings: {
                format: "JSON",
            },
        },
    }],
});
import pulumi
import pulumi_aws as aws

example = aws.quicksight.DataSet("example",
    data_set_id="example-id",
    name="example-name",
    import_mode="SPICE",
    physical_table_maps=[{
        "physical_table_map_id": "example-id",
        "s3_source": {
            "data_source_arn": example_aws_quicksight_data_source["arn"],
            "input_columns": [{
                "name": "Column1",
                "type": "STRING",
            }],
            "upload_settings": {
                "format": "JSON",
            },
        },
    }])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := quicksight.NewDataSet(ctx, "example", &quicksight.DataSetArgs{
			DataSetId:  pulumi.String("example-id"),
			Name:       pulumi.String("example-name"),
			ImportMode: pulumi.String("SPICE"),
			PhysicalTableMaps: quicksight.DataSetPhysicalTableMapArray{
				&quicksight.DataSetPhysicalTableMapArgs{
					PhysicalTableMapId: pulumi.String("example-id"),
					S3Source: &quicksight.DataSetPhysicalTableMapS3SourceArgs{
						DataSourceArn: pulumi.Any(exampleAwsQuicksightDataSource.Arn),
						InputColumns: quicksight.DataSetPhysicalTableMapS3SourceInputColumnArray{
							&quicksight.DataSetPhysicalTableMapS3SourceInputColumnArgs{
								Name: pulumi.String("Column1"),
								Type: pulumi.String("STRING"),
							},
						},
						UploadSettings: &quicksight.DataSetPhysicalTableMapS3SourceUploadSettingsArgs{
							Format: pulumi.String("JSON"),
						},
					},
				},
			},
		})
		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.Quicksight.DataSet("example", new()
    {
        DataSetId = "example-id",
        Name = "example-name",
        ImportMode = "SPICE",
        PhysicalTableMaps = new[]
        {
            new Aws.Quicksight.Inputs.DataSetPhysicalTableMapArgs
            {
                PhysicalTableMapId = "example-id",
                S3Source = new Aws.Quicksight.Inputs.DataSetPhysicalTableMapS3SourceArgs
                {
                    DataSourceArn = exampleAwsQuicksightDataSource.Arn,
                    InputColumns = new[]
                    {
                        new Aws.Quicksight.Inputs.DataSetPhysicalTableMapS3SourceInputColumnArgs
                        {
                            Name = "Column1",
                            Type = "STRING",
                        },
                    },
                    UploadSettings = new Aws.Quicksight.Inputs.DataSetPhysicalTableMapS3SourceUploadSettingsArgs
                    {
                        Format = "JSON",
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.quicksight.DataSet;
import com.pulumi.aws.quicksight.DataSetArgs;
import com.pulumi.aws.quicksight.inputs.DataSetPhysicalTableMapArgs;
import com.pulumi.aws.quicksight.inputs.DataSetPhysicalTableMapS3SourceArgs;
import com.pulumi.aws.quicksight.inputs.DataSetPhysicalTableMapS3SourceUploadSettingsArgs;
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 DataSet("example", DataSetArgs.builder()
            .dataSetId("example-id")
            .name("example-name")
            .importMode("SPICE")
            .physicalTableMaps(DataSetPhysicalTableMapArgs.builder()
                .physicalTableMapId("example-id")
                .s3Source(DataSetPhysicalTableMapS3SourceArgs.builder()
                    .dataSourceArn(exampleAwsQuicksightDataSource.arn())
                    .inputColumns(DataSetPhysicalTableMapS3SourceInputColumnArgs.builder()
                        .name("Column1")
                        .type("STRING")
                        .build())
                    .uploadSettings(DataSetPhysicalTableMapS3SourceUploadSettingsArgs.builder()
                        .format("JSON")
                        .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:quicksight:DataSet
    properties:
      dataSetId: example-id
      name: example-name
      importMode: SPICE
      physicalTableMaps:
        - physicalTableMapId: example-id
          s3Source:
            dataSourceArn: ${exampleAwsQuicksightDataSource.arn}
            inputColumns:
              - name: Column1
                type: STRING
            uploadSettings:
              format: JSON

The physicalTableMaps property defines where data comes from. The s3Source block points to a QuickSight data source (which references an S3 bucket), specifies the column schema through inputColumns, and sets the file format. The importMode property controls whether data is imported into SPICE (in-memory) or queried directly; SPICE provides faster performance for interactive analysis.

Restrict column access with permission rules

Organizations often need to hide sensitive columns from certain users while allowing them to view and analyze other parts of the dataset.

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

const example = new aws.quicksight.DataSet("example", {
    dataSetId: "example-id",
    name: "example-name",
    importMode: "SPICE",
    physicalTableMaps: [{
        physicalTableMapId: "example-id",
        s3Source: {
            dataSourceArn: exampleAwsQuicksightDataSource.arn,
            inputColumns: [{
                name: "Column1",
                type: "STRING",
            }],
            uploadSettings: {
                format: "JSON",
            },
        },
    }],
    columnLevelPermissionRules: [{
        columnNames: ["Column1"],
        principals: [exampleAwsQuicksightUser.arn],
    }],
});
import pulumi
import pulumi_aws as aws

example = aws.quicksight.DataSet("example",
    data_set_id="example-id",
    name="example-name",
    import_mode="SPICE",
    physical_table_maps=[{
        "physical_table_map_id": "example-id",
        "s3_source": {
            "data_source_arn": example_aws_quicksight_data_source["arn"],
            "input_columns": [{
                "name": "Column1",
                "type": "STRING",
            }],
            "upload_settings": {
                "format": "JSON",
            },
        },
    }],
    column_level_permission_rules=[{
        "column_names": ["Column1"],
        "principals": [example_aws_quicksight_user["arn"]],
    }])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := quicksight.NewDataSet(ctx, "example", &quicksight.DataSetArgs{
			DataSetId:  pulumi.String("example-id"),
			Name:       pulumi.String("example-name"),
			ImportMode: pulumi.String("SPICE"),
			PhysicalTableMaps: quicksight.DataSetPhysicalTableMapArray{
				&quicksight.DataSetPhysicalTableMapArgs{
					PhysicalTableMapId: pulumi.String("example-id"),
					S3Source: &quicksight.DataSetPhysicalTableMapS3SourceArgs{
						DataSourceArn: pulumi.Any(exampleAwsQuicksightDataSource.Arn),
						InputColumns: quicksight.DataSetPhysicalTableMapS3SourceInputColumnArray{
							&quicksight.DataSetPhysicalTableMapS3SourceInputColumnArgs{
								Name: pulumi.String("Column1"),
								Type: pulumi.String("STRING"),
							},
						},
						UploadSettings: &quicksight.DataSetPhysicalTableMapS3SourceUploadSettingsArgs{
							Format: pulumi.String("JSON"),
						},
					},
				},
			},
			ColumnLevelPermissionRules: quicksight.DataSetColumnLevelPermissionRuleArray{
				&quicksight.DataSetColumnLevelPermissionRuleArgs{
					ColumnNames: pulumi.StringArray{
						pulumi.String("Column1"),
					},
					Principals: pulumi.StringArray{
						exampleAwsQuicksightUser.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 example = new Aws.Quicksight.DataSet("example", new()
    {
        DataSetId = "example-id",
        Name = "example-name",
        ImportMode = "SPICE",
        PhysicalTableMaps = new[]
        {
            new Aws.Quicksight.Inputs.DataSetPhysicalTableMapArgs
            {
                PhysicalTableMapId = "example-id",
                S3Source = new Aws.Quicksight.Inputs.DataSetPhysicalTableMapS3SourceArgs
                {
                    DataSourceArn = exampleAwsQuicksightDataSource.Arn,
                    InputColumns = new[]
                    {
                        new Aws.Quicksight.Inputs.DataSetPhysicalTableMapS3SourceInputColumnArgs
                        {
                            Name = "Column1",
                            Type = "STRING",
                        },
                    },
                    UploadSettings = new Aws.Quicksight.Inputs.DataSetPhysicalTableMapS3SourceUploadSettingsArgs
                    {
                        Format = "JSON",
                    },
                },
            },
        },
        ColumnLevelPermissionRules = new[]
        {
            new Aws.Quicksight.Inputs.DataSetColumnLevelPermissionRuleArgs
            {
                ColumnNames = new[]
                {
                    "Column1",
                },
                Principals = new[]
                {
                    exampleAwsQuicksightUser.Arn,
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.quicksight.DataSet;
import com.pulumi.aws.quicksight.DataSetArgs;
import com.pulumi.aws.quicksight.inputs.DataSetPhysicalTableMapArgs;
import com.pulumi.aws.quicksight.inputs.DataSetPhysicalTableMapS3SourceArgs;
import com.pulumi.aws.quicksight.inputs.DataSetPhysicalTableMapS3SourceUploadSettingsArgs;
import com.pulumi.aws.quicksight.inputs.DataSetColumnLevelPermissionRuleArgs;
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 DataSet("example", DataSetArgs.builder()
            .dataSetId("example-id")
            .name("example-name")
            .importMode("SPICE")
            .physicalTableMaps(DataSetPhysicalTableMapArgs.builder()
                .physicalTableMapId("example-id")
                .s3Source(DataSetPhysicalTableMapS3SourceArgs.builder()
                    .dataSourceArn(exampleAwsQuicksightDataSource.arn())
                    .inputColumns(DataSetPhysicalTableMapS3SourceInputColumnArgs.builder()
                        .name("Column1")
                        .type("STRING")
                        .build())
                    .uploadSettings(DataSetPhysicalTableMapS3SourceUploadSettingsArgs.builder()
                        .format("JSON")
                        .build())
                    .build())
                .build())
            .columnLevelPermissionRules(DataSetColumnLevelPermissionRuleArgs.builder()
                .columnNames("Column1")
                .principals(exampleAwsQuicksightUser.arn())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:quicksight:DataSet
    properties:
      dataSetId: example-id
      name: example-name
      importMode: SPICE
      physicalTableMaps:
        - physicalTableMapId: example-id
          s3Source:
            dataSourceArn: ${exampleAwsQuicksightDataSource.arn}
            inputColumns:
              - name: Column1
                type: STRING
            uploadSettings:
              format: JSON
      columnLevelPermissionRules:
        - columnNames:
            - Column1
          principals:
            - ${exampleAwsQuicksightUser.arn}

The columnLevelPermissionRules property restricts which columns specific users can see. Each rule lists columnNames to protect and principals (user or group ARNs) who can access them. Users without permission see the dataset but cannot view or filter on restricted columns in analyses or dashboards.

Organize columns into field folders

Datasets with many columns benefit from logical grouping to help analysts find related fields quickly in the QuickSight interface.

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

const example = new aws.quicksight.DataSet("example", {
    dataSetId: "example-id",
    name: "example-name",
    importMode: "SPICE",
    physicalTableMaps: [{
        physicalTableMapId: "example-id",
        s3Source: {
            dataSourceArn: exampleAwsQuicksightDataSource.arn,
            inputColumns: [{
                name: "Column1",
                type: "STRING",
            }],
            uploadSettings: {
                format: "JSON",
            },
        },
    }],
    fieldFolders: [{
        fieldFoldersId: "example-id",
        columns: ["Column1"],
        description: "example description",
    }],
});
import pulumi
import pulumi_aws as aws

example = aws.quicksight.DataSet("example",
    data_set_id="example-id",
    name="example-name",
    import_mode="SPICE",
    physical_table_maps=[{
        "physical_table_map_id": "example-id",
        "s3_source": {
            "data_source_arn": example_aws_quicksight_data_source["arn"],
            "input_columns": [{
                "name": "Column1",
                "type": "STRING",
            }],
            "upload_settings": {
                "format": "JSON",
            },
        },
    }],
    field_folders=[{
        "field_folders_id": "example-id",
        "columns": ["Column1"],
        "description": "example description",
    }])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := quicksight.NewDataSet(ctx, "example", &quicksight.DataSetArgs{
			DataSetId:  pulumi.String("example-id"),
			Name:       pulumi.String("example-name"),
			ImportMode: pulumi.String("SPICE"),
			PhysicalTableMaps: quicksight.DataSetPhysicalTableMapArray{
				&quicksight.DataSetPhysicalTableMapArgs{
					PhysicalTableMapId: pulumi.String("example-id"),
					S3Source: &quicksight.DataSetPhysicalTableMapS3SourceArgs{
						DataSourceArn: pulumi.Any(exampleAwsQuicksightDataSource.Arn),
						InputColumns: quicksight.DataSetPhysicalTableMapS3SourceInputColumnArray{
							&quicksight.DataSetPhysicalTableMapS3SourceInputColumnArgs{
								Name: pulumi.String("Column1"),
								Type: pulumi.String("STRING"),
							},
						},
						UploadSettings: &quicksight.DataSetPhysicalTableMapS3SourceUploadSettingsArgs{
							Format: pulumi.String("JSON"),
						},
					},
				},
			},
			FieldFolders: quicksight.DataSetFieldFolderArray{
				&quicksight.DataSetFieldFolderArgs{
					FieldFoldersId: pulumi.String("example-id"),
					Columns: pulumi.StringArray{
						pulumi.String("Column1"),
					},
					Description: pulumi.String("example description"),
				},
			},
		})
		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.Quicksight.DataSet("example", new()
    {
        DataSetId = "example-id",
        Name = "example-name",
        ImportMode = "SPICE",
        PhysicalTableMaps = new[]
        {
            new Aws.Quicksight.Inputs.DataSetPhysicalTableMapArgs
            {
                PhysicalTableMapId = "example-id",
                S3Source = new Aws.Quicksight.Inputs.DataSetPhysicalTableMapS3SourceArgs
                {
                    DataSourceArn = exampleAwsQuicksightDataSource.Arn,
                    InputColumns = new[]
                    {
                        new Aws.Quicksight.Inputs.DataSetPhysicalTableMapS3SourceInputColumnArgs
                        {
                            Name = "Column1",
                            Type = "STRING",
                        },
                    },
                    UploadSettings = new Aws.Quicksight.Inputs.DataSetPhysicalTableMapS3SourceUploadSettingsArgs
                    {
                        Format = "JSON",
                    },
                },
            },
        },
        FieldFolders = new[]
        {
            new Aws.Quicksight.Inputs.DataSetFieldFolderArgs
            {
                FieldFoldersId = "example-id",
                Columns = new[]
                {
                    "Column1",
                },
                Description = "example description",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.quicksight.DataSet;
import com.pulumi.aws.quicksight.DataSetArgs;
import com.pulumi.aws.quicksight.inputs.DataSetPhysicalTableMapArgs;
import com.pulumi.aws.quicksight.inputs.DataSetPhysicalTableMapS3SourceArgs;
import com.pulumi.aws.quicksight.inputs.DataSetPhysicalTableMapS3SourceUploadSettingsArgs;
import com.pulumi.aws.quicksight.inputs.DataSetFieldFolderArgs;
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 DataSet("example", DataSetArgs.builder()
            .dataSetId("example-id")
            .name("example-name")
            .importMode("SPICE")
            .physicalTableMaps(DataSetPhysicalTableMapArgs.builder()
                .physicalTableMapId("example-id")
                .s3Source(DataSetPhysicalTableMapS3SourceArgs.builder()
                    .dataSourceArn(exampleAwsQuicksightDataSource.arn())
                    .inputColumns(DataSetPhysicalTableMapS3SourceInputColumnArgs.builder()
                        .name("Column1")
                        .type("STRING")
                        .build())
                    .uploadSettings(DataSetPhysicalTableMapS3SourceUploadSettingsArgs.builder()
                        .format("JSON")
                        .build())
                    .build())
                .build())
            .fieldFolders(DataSetFieldFolderArgs.builder()
                .fieldFoldersId("example-id")
                .columns("Column1")
                .description("example description")
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:quicksight:DataSet
    properties:
      dataSetId: example-id
      name: example-name
      importMode: SPICE
      physicalTableMaps:
        - physicalTableMapId: example-id
          s3Source:
            dataSourceArn: ${exampleAwsQuicksightDataSource.arn}
            inputColumns:
              - name: Column1
                type: STRING
            uploadSettings:
              format: JSON
      fieldFolders:
        - fieldFoldersId: example-id
          columns:
            - Column1
          description: example description

The fieldFolders property creates named groups in the QuickSight field list. Each folder has a unique fieldFoldersId, lists the columns it contains, and optionally includes a description. Folders appear in the analysis interface, making it easier to locate related fields without scrolling through long column lists.

Grant dataset access to QuickSight users

Teams need to control who can view, update, or share datasets through QuickSight’s permission system.

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

const example = new aws.quicksight.DataSet("example", {
    dataSetId: "example-id",
    name: "example-name",
    importMode: "SPICE",
    physicalTableMaps: [{
        physicalTableMapId: "example-id",
        s3Source: {
            dataSourceArn: exampleAwsQuicksightDataSource.arn,
            inputColumns: [{
                name: "Column1",
                type: "STRING",
            }],
            uploadSettings: {
                format: "JSON",
            },
        },
    }],
    permissions: [{
        actions: [
            "quicksight:DescribeDataSet",
            "quicksight:DescribeDataSetPermissions",
            "quicksight:PassDataSet",
            "quicksight:DescribeIngestion",
            "quicksight:ListIngestions",
        ],
        principal: exampleAwsQuicksightUser.arn,
    }],
});
import pulumi
import pulumi_aws as aws

example = aws.quicksight.DataSet("example",
    data_set_id="example-id",
    name="example-name",
    import_mode="SPICE",
    physical_table_maps=[{
        "physical_table_map_id": "example-id",
        "s3_source": {
            "data_source_arn": example_aws_quicksight_data_source["arn"],
            "input_columns": [{
                "name": "Column1",
                "type": "STRING",
            }],
            "upload_settings": {
                "format": "JSON",
            },
        },
    }],
    permissions=[{
        "actions": [
            "quicksight:DescribeDataSet",
            "quicksight:DescribeDataSetPermissions",
            "quicksight:PassDataSet",
            "quicksight:DescribeIngestion",
            "quicksight:ListIngestions",
        ],
        "principal": example_aws_quicksight_user["arn"],
    }])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := quicksight.NewDataSet(ctx, "example", &quicksight.DataSetArgs{
			DataSetId:  pulumi.String("example-id"),
			Name:       pulumi.String("example-name"),
			ImportMode: pulumi.String("SPICE"),
			PhysicalTableMaps: quicksight.DataSetPhysicalTableMapArray{
				&quicksight.DataSetPhysicalTableMapArgs{
					PhysicalTableMapId: pulumi.String("example-id"),
					S3Source: &quicksight.DataSetPhysicalTableMapS3SourceArgs{
						DataSourceArn: pulumi.Any(exampleAwsQuicksightDataSource.Arn),
						InputColumns: quicksight.DataSetPhysicalTableMapS3SourceInputColumnArray{
							&quicksight.DataSetPhysicalTableMapS3SourceInputColumnArgs{
								Name: pulumi.String("Column1"),
								Type: pulumi.String("STRING"),
							},
						},
						UploadSettings: &quicksight.DataSetPhysicalTableMapS3SourceUploadSettingsArgs{
							Format: pulumi.String("JSON"),
						},
					},
				},
			},
			Permissions: quicksight.DataSetPermissionArray{
				&quicksight.DataSetPermissionArgs{
					Actions: pulumi.StringArray{
						pulumi.String("quicksight:DescribeDataSet"),
						pulumi.String("quicksight:DescribeDataSetPermissions"),
						pulumi.String("quicksight:PassDataSet"),
						pulumi.String("quicksight:DescribeIngestion"),
						pulumi.String("quicksight:ListIngestions"),
					},
					Principal: pulumi.Any(exampleAwsQuicksightUser.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 example = new Aws.Quicksight.DataSet("example", new()
    {
        DataSetId = "example-id",
        Name = "example-name",
        ImportMode = "SPICE",
        PhysicalTableMaps = new[]
        {
            new Aws.Quicksight.Inputs.DataSetPhysicalTableMapArgs
            {
                PhysicalTableMapId = "example-id",
                S3Source = new Aws.Quicksight.Inputs.DataSetPhysicalTableMapS3SourceArgs
                {
                    DataSourceArn = exampleAwsQuicksightDataSource.Arn,
                    InputColumns = new[]
                    {
                        new Aws.Quicksight.Inputs.DataSetPhysicalTableMapS3SourceInputColumnArgs
                        {
                            Name = "Column1",
                            Type = "STRING",
                        },
                    },
                    UploadSettings = new Aws.Quicksight.Inputs.DataSetPhysicalTableMapS3SourceUploadSettingsArgs
                    {
                        Format = "JSON",
                    },
                },
            },
        },
        Permissions = new[]
        {
            new Aws.Quicksight.Inputs.DataSetPermissionArgs
            {
                Actions = new[]
                {
                    "quicksight:DescribeDataSet",
                    "quicksight:DescribeDataSetPermissions",
                    "quicksight:PassDataSet",
                    "quicksight:DescribeIngestion",
                    "quicksight:ListIngestions",
                },
                Principal = exampleAwsQuicksightUser.Arn,
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.quicksight.DataSet;
import com.pulumi.aws.quicksight.DataSetArgs;
import com.pulumi.aws.quicksight.inputs.DataSetPhysicalTableMapArgs;
import com.pulumi.aws.quicksight.inputs.DataSetPhysicalTableMapS3SourceArgs;
import com.pulumi.aws.quicksight.inputs.DataSetPhysicalTableMapS3SourceUploadSettingsArgs;
import com.pulumi.aws.quicksight.inputs.DataSetPermissionArgs;
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 DataSet("example", DataSetArgs.builder()
            .dataSetId("example-id")
            .name("example-name")
            .importMode("SPICE")
            .physicalTableMaps(DataSetPhysicalTableMapArgs.builder()
                .physicalTableMapId("example-id")
                .s3Source(DataSetPhysicalTableMapS3SourceArgs.builder()
                    .dataSourceArn(exampleAwsQuicksightDataSource.arn())
                    .inputColumns(DataSetPhysicalTableMapS3SourceInputColumnArgs.builder()
                        .name("Column1")
                        .type("STRING")
                        .build())
                    .uploadSettings(DataSetPhysicalTableMapS3SourceUploadSettingsArgs.builder()
                        .format("JSON")
                        .build())
                    .build())
                .build())
            .permissions(DataSetPermissionArgs.builder()
                .actions(                
                    "quicksight:DescribeDataSet",
                    "quicksight:DescribeDataSetPermissions",
                    "quicksight:PassDataSet",
                    "quicksight:DescribeIngestion",
                    "quicksight:ListIngestions")
                .principal(exampleAwsQuicksightUser.arn())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:quicksight:DataSet
    properties:
      dataSetId: example-id
      name: example-name
      importMode: SPICE
      physicalTableMaps:
        - physicalTableMapId: example-id
          s3Source:
            dataSourceArn: ${exampleAwsQuicksightDataSource.arn}
            inputColumns:
              - name: Column1
                type: STRING
            uploadSettings:
              format: JSON
      permissions:
        - actions:
            - quicksight:DescribeDataSet
            - quicksight:DescribeDataSetPermissions
            - quicksight:PassDataSet
            - quicksight:DescribeIngestion
            - quicksight:ListIngestions
          principal: ${exampleAwsQuicksightUser.arn}

The permissions property defines dataset-level access. Each permission entry specifies a principal (user or group ARN) and a list of actions they can perform. Common actions include DescribeDataSet (view metadata), PassDataSet (use in analyses), and DescribeIngestion (check refresh status). These permissions control dataset management, not row or column visibility.

Filter rows based on user tags

Applications embedding QuickSight dashboards often need to show different rows to different users based on their attributes or roles.

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

const example = new aws.quicksight.DataSet("example", {
    dataSetId: "example-id",
    name: "example-name",
    importMode: "SPICE",
    physicalTableMaps: [{
        physicalTableMapId: "example-id",
        s3Source: {
            dataSourceArn: exampleAwsQuicksightDataSource.arn,
            inputColumns: [{
                name: "Column1",
                type: "STRING",
            }],
            uploadSettings: {
                format: "JSON",
            },
        },
    }],
    rowLevelPermissionTagConfiguration: {
        status: "ENABLED",
        tagRules: [{
            columnName: "Column1",
            tagKey: "tagkey",
            matchAllValue: "*",
            tagMultiValueDelimiter: ",",
        }],
    },
});
import pulumi
import pulumi_aws as aws

example = aws.quicksight.DataSet("example",
    data_set_id="example-id",
    name="example-name",
    import_mode="SPICE",
    physical_table_maps=[{
        "physical_table_map_id": "example-id",
        "s3_source": {
            "data_source_arn": example_aws_quicksight_data_source["arn"],
            "input_columns": [{
                "name": "Column1",
                "type": "STRING",
            }],
            "upload_settings": {
                "format": "JSON",
            },
        },
    }],
    row_level_permission_tag_configuration={
        "status": "ENABLED",
        "tag_rules": [{
            "column_name": "Column1",
            "tag_key": "tagkey",
            "match_all_value": "*",
            "tag_multi_value_delimiter": ",",
        }],
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := quicksight.NewDataSet(ctx, "example", &quicksight.DataSetArgs{
			DataSetId:  pulumi.String("example-id"),
			Name:       pulumi.String("example-name"),
			ImportMode: pulumi.String("SPICE"),
			PhysicalTableMaps: quicksight.DataSetPhysicalTableMapArray{
				&quicksight.DataSetPhysicalTableMapArgs{
					PhysicalTableMapId: pulumi.String("example-id"),
					S3Source: &quicksight.DataSetPhysicalTableMapS3SourceArgs{
						DataSourceArn: pulumi.Any(exampleAwsQuicksightDataSource.Arn),
						InputColumns: quicksight.DataSetPhysicalTableMapS3SourceInputColumnArray{
							&quicksight.DataSetPhysicalTableMapS3SourceInputColumnArgs{
								Name: pulumi.String("Column1"),
								Type: pulumi.String("STRING"),
							},
						},
						UploadSettings: &quicksight.DataSetPhysicalTableMapS3SourceUploadSettingsArgs{
							Format: pulumi.String("JSON"),
						},
					},
				},
			},
			RowLevelPermissionTagConfiguration: &quicksight.DataSetRowLevelPermissionTagConfigurationArgs{
				Status: pulumi.String("ENABLED"),
				TagRules: quicksight.DataSetRowLevelPermissionTagConfigurationTagRuleArray{
					&quicksight.DataSetRowLevelPermissionTagConfigurationTagRuleArgs{
						ColumnName:             pulumi.String("Column1"),
						TagKey:                 pulumi.String("tagkey"),
						MatchAllValue:          pulumi.String("*"),
						TagMultiValueDelimiter: pulumi.String(","),
					},
				},
			},
		})
		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.Quicksight.DataSet("example", new()
    {
        DataSetId = "example-id",
        Name = "example-name",
        ImportMode = "SPICE",
        PhysicalTableMaps = new[]
        {
            new Aws.Quicksight.Inputs.DataSetPhysicalTableMapArgs
            {
                PhysicalTableMapId = "example-id",
                S3Source = new Aws.Quicksight.Inputs.DataSetPhysicalTableMapS3SourceArgs
                {
                    DataSourceArn = exampleAwsQuicksightDataSource.Arn,
                    InputColumns = new[]
                    {
                        new Aws.Quicksight.Inputs.DataSetPhysicalTableMapS3SourceInputColumnArgs
                        {
                            Name = "Column1",
                            Type = "STRING",
                        },
                    },
                    UploadSettings = new Aws.Quicksight.Inputs.DataSetPhysicalTableMapS3SourceUploadSettingsArgs
                    {
                        Format = "JSON",
                    },
                },
            },
        },
        RowLevelPermissionTagConfiguration = new Aws.Quicksight.Inputs.DataSetRowLevelPermissionTagConfigurationArgs
        {
            Status = "ENABLED",
            TagRules = new[]
            {
                new Aws.Quicksight.Inputs.DataSetRowLevelPermissionTagConfigurationTagRuleArgs
                {
                    ColumnName = "Column1",
                    TagKey = "tagkey",
                    MatchAllValue = "*",
                    TagMultiValueDelimiter = ",",
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.quicksight.DataSet;
import com.pulumi.aws.quicksight.DataSetArgs;
import com.pulumi.aws.quicksight.inputs.DataSetPhysicalTableMapArgs;
import com.pulumi.aws.quicksight.inputs.DataSetPhysicalTableMapS3SourceArgs;
import com.pulumi.aws.quicksight.inputs.DataSetPhysicalTableMapS3SourceUploadSettingsArgs;
import com.pulumi.aws.quicksight.inputs.DataSetRowLevelPermissionTagConfigurationArgs;
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 DataSet("example", DataSetArgs.builder()
            .dataSetId("example-id")
            .name("example-name")
            .importMode("SPICE")
            .physicalTableMaps(DataSetPhysicalTableMapArgs.builder()
                .physicalTableMapId("example-id")
                .s3Source(DataSetPhysicalTableMapS3SourceArgs.builder()
                    .dataSourceArn(exampleAwsQuicksightDataSource.arn())
                    .inputColumns(DataSetPhysicalTableMapS3SourceInputColumnArgs.builder()
                        .name("Column1")
                        .type("STRING")
                        .build())
                    .uploadSettings(DataSetPhysicalTableMapS3SourceUploadSettingsArgs.builder()
                        .format("JSON")
                        .build())
                    .build())
                .build())
            .rowLevelPermissionTagConfiguration(DataSetRowLevelPermissionTagConfigurationArgs.builder()
                .status("ENABLED")
                .tagRules(DataSetRowLevelPermissionTagConfigurationTagRuleArgs.builder()
                    .columnName("Column1")
                    .tagKey("tagkey")
                    .matchAllValue("*")
                    .tagMultiValueDelimiter(",")
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:quicksight:DataSet
    properties:
      dataSetId: example-id
      name: example-name
      importMode: SPICE
      physicalTableMaps:
        - physicalTableMapId: example-id
          s3Source:
            dataSourceArn: ${exampleAwsQuicksightDataSource.arn}
            inputColumns:
              - name: Column1
                type: STRING
            uploadSettings:
              format: JSON
      rowLevelPermissionTagConfiguration:
        status: ENABLED
        tagRules:
          - columnName: Column1
            tagKey: tagkey
            matchAllValue: '*'
            tagMultiValueDelimiter: ','

The rowLevelPermissionTagConfiguration property filters rows dynamically using session tags passed during embedded dashboard access. Each tagRule maps a columnName in the dataset to a tagKey from the user session. When a user views the dashboard, QuickSight only shows rows where the column value matches their session tag. The matchAllValue property defines a wildcard that grants access to all rows. This approach works for anonymous embedding scenarios where user identity comes from session tags rather than QuickSight user accounts.

Beyond these examples

These snippets focus on specific dataset features: S3 data import and SPICE configuration, column and row-level security, and field organization and dataset permissions. They’re intentionally minimal rather than full analytics solutions.

The examples reference pre-existing infrastructure such as QuickSight data sources (S3, RDS, Redshift, etc.), QuickSight users and groups for permission assignment, and S3 buckets with data files. They focus on configuring the dataset rather than provisioning the underlying data infrastructure.

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

  • Logical table transformations (joins, filters, calculated fields)
  • Column groups for geospatial hierarchies
  • Refresh schedules for SPICE datasets (refreshProperties)
  • Direct query mode configuration (importMode: DIRECT_QUERY)

These omissions are intentional: the goal is to illustrate how each dataset feature is wired, not provide drop-in analytics modules. See the QuickSight DataSet resource reference for all available configuration options.

Let's create AWS QuickSight Data Sets

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Import Modes & Data Loading
What's the difference between SPICE and DIRECT_QUERY import modes?
SPICE loads data into QuickSight’s in-memory engine for faster queries, while DIRECT_QUERY queries the source database directly. Choose SPICE for performance or DIRECT_QUERY for real-time data.
Can I use refresh properties with DIRECT_QUERY mode?
No, refreshProperties is only valid when importMode is set to SPICE. Direct query mode doesn’t cache data, so refresh configuration doesn’t apply.
How do I configure automatic data refresh for my dataset?
Set refreshProperties with your refresh schedule, but only when using importMode of SPICE. DIRECT_QUERY mode doesn’t support refresh configuration.
Security & Access Control
What's the difference between row-level and column-level security?
Column-level security (via columnLevelPermissionRules) restricts which columns users can see. Row-level security (via rowLevelPermissionDataSet or rowLevelPermissionTagConfiguration) restricts which rows users can access.
How do I set up row-level security for my dataset?

You have two options:

  1. Standard RLS - Use rowLevelPermissionDataSet for general row-level security
  2. Tag-based RLS - Use rowLevelPermissionTagConfiguration for anonymous embedding scenarios only
Can I use row-level permission tags in embedded dashboards?
Row-level security tags are currently supported for anonymous embedding only. For authenticated embedding, use rowLevelPermissionDataSet instead.
What is the useAs property for?
Setting useAs to RLS_RULES designates the dataset as a Row Level Security rules dataset, used to control data access at the row level in analyses and dashboards. This is the only valid value.
How do I restrict access to specific columns?
Configure columnLevelPermissionRules with an array of column names and the principals (user/group ARNs) who can access them.
What permissions can I grant on a dataset?
Common actions include quicksight:DescribeDataSet, quicksight:DescribeDataSetPermissions, quicksight:PassDataSet, quicksight:DescribeIngestion, and quicksight:ListIngestions. You can grant up to 64 permission entries.
Configuration & Limits
What properties can't I change after creating a dataset?
Three properties are immutable: dataSetId, awsAccountId, and useAs. Changing any of these requires replacing the entire dataset resource.
How many logical table maps can I configure?
You can configure a maximum of 1 logical table map entry per dataset. This map defines how data from physical tables is combined and transformed.
Is there a limit on dataset permissions?
Yes, you can configure a maximum of 64 permission items on a dataset.

Using a different cloud?

Explore analytics guides for other cloud providers: