Skip to content
v2.274.0

Amazon DynamoDB Construct Library ​

The DynamoDB construct library has two table constructs - Table and TableV2. TableV2 is the preferred construct for all use cases, including creating a single table or a table with multiple replicas.

Table API documentation

Here is a minimal deployable DynamoDB table using TableV2:

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
});
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING)
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING }
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
})

By default, TableV2 will create a single table in the main deployment region referred to as the primary table. The properties of the primary table are configurable via TableV2 properties. For example, consider the following DynamoDB table created using the TableV2 construct defined in a Stack being deployed to us-west-2:

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  contributorInsightsSpecification: {
    enabled: true,
  },
  tableClass: dynamodb.TableClass.STANDARD_INFREQUENT_ACCESS,
  pointInTimeRecoverySpecification: {
    pointInTimeRecoveryEnabled: true,
  },
});
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    contributor_insights_specification=dynamodb.ContributorInsightsSpecification(
        enabled=True
    ),
    table_class=dynamodb.TableClass.STANDARD_INFREQUENT_ACCESS,
    point_in_time_recovery_specification=dynamodb.PointInTimeRecoverySpecification(
        point_in_time_recovery_enabled=True
    )
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .contributorInsightsSpecification(ContributorInsightsSpecification.builder()
                .enabled(true)
                .build())
        .tableClass(TableClass.STANDARD_INFREQUENT_ACCESS)
        .pointInTimeRecoverySpecification(PointInTimeRecoverySpecification.builder()
                .pointInTimeRecoveryEnabled(true)
                .build())
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    ContributorInsightsSpecification = new ContributorInsightsSpecification {
        Enabled = true
    },
    TableClass = TableClass.STANDARD_INFREQUENT_ACCESS,
    PointInTimeRecoverySpecification = new PointInTimeRecoverySpecification {
        PointInTimeRecoveryEnabled = true
    }
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	ContributorInsightsSpecification: &ContributorInsightsSpecification{
		Enabled: jsii.Boolean(true),
	},
	TableClass: dynamodb.TableClass_STANDARD_INFREQUENT_ACCESS,
	PointInTimeRecoverySpecification: &PointInTimeRecoverySpecification{
		PointInTimeRecoveryEnabled: jsii.Boolean(true),
	},
})

The above TableV2 definition will result in the provisioning of a single table in us-west-2 with properties that match the properties set on the TableV2 instance.

Further reading: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GlobalTables.html

Replicas ​

The TableV2 construct can be configured with replica tables. This will enable you to work with your table as a global table. To do this, the TableV2 construct must be defined in a Stack with a defined region. The main deployment region must not be given as a replica because this is created by default with the TableV2 construct. The following is a minimal example of defining TableV2 with replicas. This TableV2 definition will provision three copies of the table - one in us-west-2 (primary deployment region), one in us-east-1, and one in us-east-2.

ts
import * as cdk from 'aws-cdk-lib';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack', { env: { region: 'us-west-2' } });

const globalTable = new dynamodb.TableV2(stack, 'GlobalTable', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  replicas: [
    { region: 'us-east-1' },
    { region: 'us-east-2' },
  ],
});
python
import aws_cdk as cdk


app = cdk.App()
stack = cdk.Stack(app, "Stack", env=cdk.Environment(region="us-west-2"))

global_table = dynamodb.TableV2(stack, "GlobalTable",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    replicas=[dynamodb.ReplicaTableProps(region="us-east-1"), dynamodb.ReplicaTableProps(region="us-east-2")
    ]
)
java
import software.amazon.awscdk.*;


App app = new App();
Stack stack = Stack.Builder.create(app, "Stack").env(Environment.builder().region("us-west-2").build()).build();

TableV2 globalTable = TableV2.Builder.create(stack, "GlobalTable")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .replicas(List.of(ReplicaTableProps.builder().region("us-east-1").build(), ReplicaTableProps.builder().region("us-east-2").build()))
        .build();
csharp
using Amazon.CDK;


var app = new App();
var stack = new Stack(app, "Stack", new StackProps { Env = new Environment { Region = "us-west-2" } });

var globalTable = new TableV2(stack, "GlobalTable", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    Replicas = new [] { new ReplicaTableProps { Region = "us-east-1" }, new ReplicaTableProps { Region = "us-east-2" } }
});
go
import "github.com/aws/aws-cdk-go/awscdk"


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})

globalTable := dynamodb.NewTableV2(stack, jsii.String("GlobalTable"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-east-1"),
		},
		&ReplicaTableProps{
			Region: jsii.String("us-east-2"),
		},
	},
})

Alternatively, you can add new replicas to an instance of the TableV2 construct using the addReplica method:

ts
import * as cdk from 'aws-cdk-lib';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack', { env: { region: 'us-west-2' } });

const globalTable = new dynamodb.TableV2(stack, 'GlobalTable', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  replicas: [{ region: 'us-east-1' }],
});

globalTable.addReplica({ region: 'us-east-2', deletionProtection: true });
python
import aws_cdk as cdk


app = cdk.App()
stack = cdk.Stack(app, "Stack", env=cdk.Environment(region="us-west-2"))

global_table = dynamodb.TableV2(stack, "GlobalTable",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    replicas=[dynamodb.ReplicaTableProps(region="us-east-1")]
)

global_table.add_replica(region="us-east-2", deletion_protection=True)
java
import software.amazon.awscdk.*;


App app = new App();
Stack stack = Stack.Builder.create(app, "Stack").env(Environment.builder().region("us-west-2").build()).build();

TableV2 globalTable = TableV2.Builder.create(stack, "GlobalTable")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .replicas(List.of(ReplicaTableProps.builder().region("us-east-1").build()))
        .build();

globalTable.addReplica(ReplicaTableProps.builder().region("us-east-2").deletionProtection(true).build());
csharp
using Amazon.CDK;


var app = new App();
var stack = new Stack(app, "Stack", new StackProps { Env = new Environment { Region = "us-west-2" } });

var globalTable = new TableV2(stack, "GlobalTable", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    Replicas = new [] { new ReplicaTableProps { Region = "us-east-1" } }
});

globalTable.AddReplica(new ReplicaTableProps { Region = "us-east-2", DeletionProtection = true });
go
import "github.com/aws/aws-cdk-go/awscdk"


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})

globalTable := dynamodb.NewTableV2(stack, jsii.String("GlobalTable"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-east-1"),
		},
	},
})

globalTable.AddReplica(&ReplicaTableProps{
	Region: jsii.String("us-east-2"),
	DeletionProtection: jsii.Boolean(true),
})

The following properties are configurable on a per-replica basis, but will be inherited from the TableV2 properties if not specified:

  • contributorInsightsSpecification
  • deletionProtection
  • pointInTimeRecoverySpecification
  • tableClass
  • readCapacity (only configurable if the TableV2 billing mode is PROVISIONED)
  • globalSecondaryIndexes (only contributorInsightsSpecification and readCapacity)

The following example shows how to define properties on a per-replica basis:

ts
import * as cdk from 'aws-cdk-lib';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack', { env: { region: 'us-west-2' } });

const globalTable = new dynamodb.TableV2(stack, 'GlobalTable', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  contributorInsightsSpecification: {
    enabled: true,
  },
  pointInTimeRecoverySpecification: {
      pointInTimeRecoveryEnabled: true,
  },
  replicas: [
    {
      region: 'us-east-1',
      tableClass: dynamodb.TableClass.STANDARD_INFREQUENT_ACCESS,
      pointInTimeRecoverySpecification: {
        pointInTimeRecoveryEnabled: false,
      },
    },
    {
      region: 'us-east-2',
      contributorInsightsSpecification: {
        enabled: false,
      },
    },
  ],
});
python
import aws_cdk as cdk


app = cdk.App()
stack = cdk.Stack(app, "Stack", env=cdk.Environment(region="us-west-2"))

global_table = dynamodb.TableV2(stack, "GlobalTable",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    contributor_insights_specification=dynamodb.ContributorInsightsSpecification(
        enabled=True
    ),
    point_in_time_recovery_specification=dynamodb.PointInTimeRecoverySpecification(
        point_in_time_recovery_enabled=True
    ),
    replicas=[dynamodb.ReplicaTableProps(
        region="us-east-1",
        table_class=dynamodb.TableClass.STANDARD_INFREQUENT_ACCESS,
        point_in_time_recovery_specification=dynamodb.PointInTimeRecoverySpecification(
            point_in_time_recovery_enabled=False
        )
    ), dynamodb.ReplicaTableProps(
        region="us-east-2",
        contributor_insights_specification=dynamodb.ContributorInsightsSpecification(
            enabled=False
        )
    )
    ]
)
java
import software.amazon.awscdk.*;


App app = new App();
Stack stack = Stack.Builder.create(app, "Stack").env(Environment.builder().region("us-west-2").build()).build();

TableV2 globalTable = TableV2.Builder.create(stack, "GlobalTable")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .contributorInsightsSpecification(ContributorInsightsSpecification.builder()
                .enabled(true)
                .build())
        .pointInTimeRecoverySpecification(PointInTimeRecoverySpecification.builder()
                .pointInTimeRecoveryEnabled(true)
                .build())
        .replicas(List.of(ReplicaTableProps.builder()
                .region("us-east-1")
                .tableClass(TableClass.STANDARD_INFREQUENT_ACCESS)
                .pointInTimeRecoverySpecification(PointInTimeRecoverySpecification.builder()
                        .pointInTimeRecoveryEnabled(false)
                        .build())
                .build(), ReplicaTableProps.builder()
                .region("us-east-2")
                .contributorInsightsSpecification(ContributorInsightsSpecification.builder()
                        .enabled(false)
                        .build())
                .build()))
        .build();
csharp
using Amazon.CDK;


var app = new App();
var stack = new Stack(app, "Stack", new StackProps { Env = new Environment { Region = "us-west-2" } });

var globalTable = new TableV2(stack, "GlobalTable", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    ContributorInsightsSpecification = new ContributorInsightsSpecification {
        Enabled = true
    },
    PointInTimeRecoverySpecification = new PointInTimeRecoverySpecification {
        PointInTimeRecoveryEnabled = true
    },
    Replicas = new [] { new ReplicaTableProps {
        Region = "us-east-1",
        TableClass = TableClass.STANDARD_INFREQUENT_ACCESS,
        PointInTimeRecoverySpecification = new PointInTimeRecoverySpecification {
            PointInTimeRecoveryEnabled = false
        }
    }, new ReplicaTableProps {
        Region = "us-east-2",
        ContributorInsightsSpecification = new ContributorInsightsSpecification {
            Enabled = false
        }
    } }
});
go
import "github.com/aws/aws-cdk-go/awscdk"


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})

globalTable := dynamodb.NewTableV2(stack, jsii.String("GlobalTable"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	ContributorInsightsSpecification: &ContributorInsightsSpecification{
		Enabled: jsii.Boolean(true),
	},
	PointInTimeRecoverySpecification: &PointInTimeRecoverySpecification{
		PointInTimeRecoveryEnabled: jsii.Boolean(true),
	},
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-east-1"),
			TableClass: dynamodb.TableClass_STANDARD_INFREQUENT_ACCESS,
			PointInTimeRecoverySpecification: &PointInTimeRecoverySpecification{
				PointInTimeRecoveryEnabled: jsii.Boolean(false),
			},
		},
		&ReplicaTableProps{
			Region: jsii.String("us-east-2"),
			ContributorInsightsSpecification: &ContributorInsightsSpecification{
				Enabled: jsii.Boolean(false),
			},
		},
	},
})

To obtain an ITableV2 reference to a specific replica table, call the replica method on an instance of the TableV2 construct and pass the replica region as an argument:

ts
import * as cdk from 'aws-cdk-lib';

declare const user: iam.User;

class FooStack extends cdk.Stack {
  public readonly globalTable: dynamodb.TableV2;

  public constructor(scope: Construct, id: string, props: cdk.StackProps) {
    super(scope, id, props);

    this.globalTable = new dynamodb.TableV2(this, 'GlobalTable', {
      partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
      replicas: [
        { region: 'us-east-1' },
        { region: 'us-east-2' },
      ],
    });
  }
}

interface BarStackProps extends cdk.StackProps {
  readonly replicaTable: dynamodb.ITableV2;
}

class BarStack extends cdk.Stack {
  public constructor(scope: Construct, id: string, props: BarStackProps) {
    super(scope, id, props);

    // user is given grantWriteData permissions to replica in us-east-1
    props.replicaTable.grantWriteData(user);
  }
}

const app = new cdk.App();

const fooStack = new FooStack(app, 'FooStack', { env: { region: 'us-west-2' } });
const barStack = new BarStack(app, 'BarStack', {
  replicaTable: fooStack.globalTable.replica('us-east-1'),
  env: { region: 'us-east-1' },
});
python
import aws_cdk as cdk

# user: iam.User


class FooStack(cdk.Stack):

    def __init__(self, scope, id, *, description=None, env=None, stackName=None, tags=None, notificationArns=None, synthesizer=None, terminationProtection=None, analyticsReporting=None, crossRegionReferences=None, permissionsBoundary=None, suppressTemplateIndentation=None, propertyInjectors=None):
        super().__init__(scope, id, description=description, env=env, stackName=stackName, tags=tags, notificationArns=notificationArns, synthesizer=synthesizer, terminationProtection=terminationProtection, analyticsReporting=analyticsReporting, crossRegionReferences=crossRegionReferences, permissionsBoundary=permissionsBoundary, suppressTemplateIndentation=suppressTemplateIndentation, propertyInjectors=propertyInjectors)

        self.global_table = dynamodb.TableV2(self, "GlobalTable",
            partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
            replicas=[dynamodb.ReplicaTableProps(region="us-east-1"), dynamodb.ReplicaTableProps(region="us-east-2")
            ]
        )

class BarStack(cdk.Stack):
    def __init__(self, scope, id, *, replicaTable, description=None, env=None, stackName=None, tags=None, notificationArns=None, synthesizer=None, terminationProtection=None, analyticsReporting=None, crossRegionReferences=None, permissionsBoundary=None, suppressTemplateIndentation=None, propertyInjectors=None):
        super().__init__(scope, id, replicaTable=replicaTable, description=description, env=env, stackName=stackName, tags=tags, notificationArns=notificationArns, synthesizer=synthesizer, terminationProtection=terminationProtection, analyticsReporting=analyticsReporting, crossRegionReferences=crossRegionReferences, permissionsBoundary=permissionsBoundary, suppressTemplateIndentation=suppressTemplateIndentation, propertyInjectors=propertyInjectors)

        # user is given grantWriteData permissions to replica in us-east-1
        replica_table.grant_write_data(user)

app = cdk.App()

foo_stack = FooStack(app, "FooStack", env=cdk.Environment(region="us-west-2"))
bar_stack = BarStack(app, "BarStack",
    replica_table=foo_stack.global_table.replica("us-east-1"),
    env=cdk.Environment(region="us-east-1")
)
java
import software.amazon.awscdk.*;

User user;


public class FooStack extends Stack {
    public final TableV2 globalTable;

    public FooStack(Construct scope, String id, StackProps props) {
        super(scope, id, props);

        this.globalTable = TableV2.Builder.create(this, "GlobalTable")
                .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
                .replicas(List.of(ReplicaTableProps.builder().region("us-east-1").build(), ReplicaTableProps.builder().region("us-east-2").build()))
                .build();
    }
}

public class BarStackProps extends StackProps {
    private ITableV2 replicaTable;
    public ITableV2 getReplicaTable() {
        return this.replicaTable;
    }
    public BarStackProps replicaTable(ITableV2 replicaTable) {
        this.replicaTable = replicaTable;
        return this;
    }
}

public class BarStack extends Stack {
    public BarStack(Construct scope, String id, BarStackProps props) {
        super(scope, id, props);

        // user is given grantWriteData permissions to replica in us-east-1
        props.replicaTable.grantWriteData(user);
    }
}

App app = new App();

FooStack fooStack = FooStack.Builder.create(app, "FooStack").env(Environment.builder().region("us-west-2").build()).build();
BarStack barStack = new BarStack(app, "BarStack", new BarStackProps()
        .replicaTable(fooStack.globalTable.replica("us-east-1"))
        .env(Environment.builder().region("us-east-1").build())
        );
csharp
using Amazon.CDK;

User user;


class FooStack : Stack
{
    public TableV2 GlobalTable { get; }

    public FooStack(Construct scope, string id, StackProps props) : base(scope, id, props)
    {

        GlobalTable = new TableV2(this, "GlobalTable", new TablePropsV2 {
            PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
            Replicas = new [] { new ReplicaTableProps { Region = "us-east-1" }, new ReplicaTableProps { Region = "us-east-2" } }
        });
    }
}

class BarStackProps : StackProps
{
    public ITableV2 ReplicaTable { get; set; }
}

class BarStack : Stack
{
    public BarStack(Construct scope, string id, BarStackProps props) : base(scope, id, props)
    {

        // user is given grantWriteData permissions to replica in us-east-1
        props.ReplicaTable.GrantWriteData(user);
    }
}

var app = new App();

var fooStack = new FooStack(app, "FooStack", new StackProps { Env = new Environment { Region = "us-west-2" } });
var barStack = new BarStack(app, "BarStack", new BarStackProps {
    ReplicaTable = fooStack.GlobalTable.Replica("us-east-1"),
    Env = new Environment { Region = "us-east-1" }
});
go
import "github.com/aws/aws-cdk-go/awscdk"

var user User


type fooStack struct {
	Stack
	globalTable TableV2
}

func newFooStack(scope Construct, id *string, props StackProps) *fooStack {
	this := &fooStack{}
	cdk.NewStack_Override(this, scope, id, props)

	this.globalTable = dynamodb.NewTableV2(this, jsii.String("GlobalTable"), &TablePropsV2{
		PartitionKey: &Attribute{
			Name: jsii.String("pk"),
			Type: dynamodb.AttributeType_STRING,
		},
		Replicas: []ReplicaTableProps{
			&ReplicaTableProps{
				Region: jsii.String("us-east-1"),
			},
			&ReplicaTableProps{
				Region: jsii.String("us-east-2"),
			},
		},
	})
	return this
}

type barStackProps struct {
	StackProps
	replicaTable ITableV2
}

type barStack struct {
	Stack
}

func newBarStack(scope Construct, id *string, props barStackProps) *barStack {
	this := &barStack{}
	cdk.NewStack_Override(this, scope, id, props)

	// user is given grantWriteData permissions to replica in us-east-1
	*props.replicaTable.GrantWriteData(user)
	return this
}

app := cdk.NewApp()

fooStack := NewFooStack(app, jsii.String("FooStack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})
barStack := NewBarStack(app, jsii.String("BarStack"), &barStackProps{
	replicaTable: fooStack.globalTable.Replica(jsii.String("us-east-1")),
	env: &Environment{
		Region: jsii.String("us-east-1"),
	},
})

Note: You can create an instance of the TableV2 construct with as many replicas as needed as long as there is only one replica per region. After table creation you can add or remove replicas, but you can only add or remove a single replica in each update.

Multi-Account Global Tables ​

Multi-account global tables extend DynamoDB replication across AWS accounts, providing enhanced security, governance, and fault isolation. Each replica resides in a separate AWS account, enabling account-level isolation and alignment with organizational structures.

Creating Multi-Account Replicas ​

For tables defined in the same CDK application, use the TableV2MultiAccountReplica construct:

ts
import * as cdk from 'aws-cdk-lib';

const app = new cdk.App();

// Source table in Account A
const sourceStack = new cdk.Stack(app, 'SourceStack', {
  env: { region: 'us-east-2', account: '111111111111' },
});

const sourceTable = new dynamodb.TableV2(sourceStack, 'SourceTable', {
  tableName: 'MyMultiAccountTable',
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  globalTableSettingsReplicationMode: dynamodb.GlobalTableSettingsReplicationMode.ALL,
});

// Replica stack in Account B
const replicaStack = new cdk.Stack(app, 'ReplicaStack', {
  env: { region: 'us-east-1', account: '222222222222' },
});

// Create replica - permissions are automatically configured
const replica = new dynamodb.TableV2MultiAccountReplica(replicaStack, 'ReplicaTable', {
  tableName: 'MyMultiAccountTable',
  replicaSourceTable: sourceTable,
  globalTableSettingsReplicationMode: dynamodb.GlobalTableSettingsReplicationMode.ALL,
});
python
import aws_cdk as cdk


app = cdk.App()

# Source table in Account A
source_stack = cdk.Stack(app, "SourceStack",
    env=cdk.Environment(region="us-east-2", account="111111111111")
)

source_table = dynamodb.TableV2(source_stack, "SourceTable",
    table_name="MyMultiAccountTable",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    global_table_settings_replication_mode=dynamodb.GlobalTableSettingsReplicationMode.ALL
)

# Replica stack in Account B
replica_stack = cdk.Stack(app, "ReplicaStack",
    env=cdk.Environment(region="us-east-1", account="222222222222")
)

# Create replica - permissions are automatically configured
replica = dynamodb.TableV2MultiAccountReplica(replica_stack, "ReplicaTable",
    table_name="MyMultiAccountTable",
    replica_source_table=source_table,
    global_table_settings_replication_mode=dynamodb.GlobalTableSettingsReplicationMode.ALL
)
java
import software.amazon.awscdk.*;


App app = new App();

// Source table in Account A
Stack sourceStack = Stack.Builder.create(app, "SourceStack")
        .env(Environment.builder().region("us-east-2").account("111111111111").build())
        .build();

TableV2 sourceTable = TableV2.Builder.create(sourceStack, "SourceTable")
        .tableName("MyMultiAccountTable")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .globalTableSettingsReplicationMode(GlobalTableSettingsReplicationMode.ALL)
        .build();

// Replica stack in Account B
Stack replicaStack = Stack.Builder.create(app, "ReplicaStack")
        .env(Environment.builder().region("us-east-1").account("222222222222").build())
        .build();

// Create replica - permissions are automatically configured
TableV2MultiAccountReplica replica = TableV2MultiAccountReplica.Builder.create(replicaStack, "ReplicaTable")
        .tableName("MyMultiAccountTable")
        .replicaSourceTable(sourceTable)
        .globalTableSettingsReplicationMode(GlobalTableSettingsReplicationMode.ALL)
        .build();
csharp
using Amazon.CDK;


var app = new App();

// Source table in Account A
var sourceStack = new Stack(app, "SourceStack", new StackProps {
    Env = new Environment { Region = "us-east-2", Account = "111111111111" }
});

var sourceTable = new TableV2(sourceStack, "SourceTable", new TablePropsV2 {
    TableName = "MyMultiAccountTable",
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    GlobalTableSettingsReplicationMode = GlobalTableSettingsReplicationMode.ALL
});

// Replica stack in Account B
var replicaStack = new Stack(app, "ReplicaStack", new StackProps {
    Env = new Environment { Region = "us-east-1", Account = "222222222222" }
});

// Create replica - permissions are automatically configured
var replica = new TableV2MultiAccountReplica(replicaStack, "ReplicaTable", new TableV2MultiAccountReplicaProps {
    TableName = "MyMultiAccountTable",
    ReplicaSourceTable = sourceTable,
    GlobalTableSettingsReplicationMode = GlobalTableSettingsReplicationMode.ALL
});
go
import "github.com/aws/aws-cdk-go/awscdk"


app := cdk.NewApp()

// Source table in Account A
sourceStack := cdk.NewStack(app, jsii.String("SourceStack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-east-2"),
		Account: jsii.String("111111111111"),
	},
})

sourceTable := dynamodb.NewTableV2(sourceStack, jsii.String("SourceTable"), &TablePropsV2{
	TableName: jsii.String("MyMultiAccountTable"),
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	GlobalTableSettingsReplicationMode: dynamodb.GlobalTableSettingsReplicationMode_ALL,
})

// Replica stack in Account B
replicaStack := cdk.NewStack(app, jsii.String("ReplicaStack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-east-1"),
		Account: jsii.String("222222222222"),
	},
})

// Create replica - permissions are automatically configured
replica := dynamodb.NewTableV2MultiAccountReplica(replicaStack, jsii.String("ReplicaTable"), &TableV2MultiAccountReplicaProps{
	TableName: jsii.String("MyMultiAccountTable"),
	ReplicaSourceTable: sourceTable,
	GlobalTableSettingsReplicationMode: dynamodb.GlobalTableSettingsReplicationMode_ALL,
})

The TableV2MultiAccountReplica construct:

  • Creates the replica table with the correct source ARN
  • Copies the key schema from the source table
  • Automatically adds resource policies to both source and replica tables
  • Validates that the replica is in a different account and region

Note: Permissions are automatically configured when both tables are in the same CDK app. For imported source tables, see "Working with Imported Tables" below.

Adding Replicas to Existing Tables ​

If the source table already exists in AWS, you cannot use automatic cross-stack references. The replica will issue a warning, and you must manually configure permissions:

ts
import * as cdk from 'aws-cdk-lib';

const app = new cdk.App();

// Source table in Account A
const sourceStack = new cdk.Stack(app, 'SourceStack', {
  env: { region: 'us-east-1', account: '111111111111' },
});

// Region us-west-2
const sourceTable = new dynamodb.TableV2(sourceStack, 'SourceTable', {
  tableName: 'MyMultiAccountTable',
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  globalTableSettingsReplicationMode: dynamodb.GlobalTableSettingsReplicationMode.ALL,
});
// After replica is deployed, update source stack with the ARN
sourceTable.grants.multiAccountReplicationTo('arn:aws:dynamodb:us-east-1:222222222222:table/MyMultiAccountTable');
python
import aws_cdk as cdk


app = cdk.App()

# Source table in Account A
source_stack = cdk.Stack(app, "SourceStack",
    env=cdk.Environment(region="us-east-1", account="111111111111")
)

# Region us-west-2
source_table = dynamodb.TableV2(source_stack, "SourceTable",
    table_name="MyMultiAccountTable",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    global_table_settings_replication_mode=dynamodb.GlobalTableSettingsReplicationMode.ALL
)
# After replica is deployed, update source stack with the ARN
source_table.grants.multi_account_replication_to("arn:aws:dynamodb:us-east-1:222222222222:table/MyMultiAccountTable")
java
import software.amazon.awscdk.*;


App app = new App();

// Source table in Account A
Stack sourceStack = Stack.Builder.create(app, "SourceStack")
        .env(Environment.builder().region("us-east-1").account("111111111111").build())
        .build();

// Region us-west-2
TableV2 sourceTable = TableV2.Builder.create(sourceStack, "SourceTable")
        .tableName("MyMultiAccountTable")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .globalTableSettingsReplicationMode(GlobalTableSettingsReplicationMode.ALL)
        .build();
// After replica is deployed, update source stack with the ARN
sourceTable.grants.multiAccountReplicationTo("arn:aws:dynamodb:us-east-1:222222222222:table/MyMultiAccountTable");
csharp
using Amazon.CDK;


var app = new App();

// Source table in Account A
var sourceStack = new Stack(app, "SourceStack", new StackProps {
    Env = new Environment { Region = "us-east-1", Account = "111111111111" }
});

// Region us-west-2
var sourceTable = new TableV2(sourceStack, "SourceTable", new TablePropsV2 {
    TableName = "MyMultiAccountTable",
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    GlobalTableSettingsReplicationMode = GlobalTableSettingsReplicationMode.ALL
});
// After replica is deployed, update source stack with the ARN
sourceTable.Grants.MultiAccountReplicationTo("arn:aws:dynamodb:us-east-1:222222222222:table/MyMultiAccountTable");
go
import "github.com/aws/aws-cdk-go/awscdk"


app := cdk.NewApp()

// Source table in Account A
sourceStack := cdk.NewStack(app, jsii.String("SourceStack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-east-1"),
		Account: jsii.String("111111111111"),
	},
})

// Region us-west-2
sourceTable := dynamodb.NewTableV2(sourceStack, jsii.String("SourceTable"), &TablePropsV2{
	TableName: jsii.String("MyMultiAccountTable"),
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	GlobalTableSettingsReplicationMode: dynamodb.GlobalTableSettingsReplicationMode_ALL,
})
// After replica is deployed, update source stack with the ARN
sourceTable.Grants.MultiAccountReplicationTo(jsii.String("arn:aws:dynamodb:us-east-1:222222222222:table/MyMultiAccountTable"))

Working with Imported Tables ​

When importing a source table, the replica will issue a warning since it cannot automatically configure permissions on the imported table:

ts
import * as cdk from 'aws-cdk-lib';

const app = new cdk.App();

const replicaStack = new cdk.Stack(app, 'ReplicaStack', {
  env: { region: 'us-east-1', account: '222222222222' },
});

// Import source table
const importedSource = dynamodb.TableV2.fromTableArn(
  replicaStack,
  'ImportedSource',
  'arn:aws:dynamodb:us-east-2:111111111111:table/MyMultiAccountTable',
);

// Create replica - will issue a warning about missing source permissions
const replica = new dynamodb.TableV2MultiAccountReplica(replicaStack, 'ReplicaTable', {
  tableName: 'MyMultiAccountTable',
  replicaSourceTable: importedSource,
  globalTableSettingsReplicationMode: dynamodb.GlobalTableSettingsReplicationMode.ALL,
});
python
import aws_cdk as cdk


app = cdk.App()

replica_stack = cdk.Stack(app, "ReplicaStack",
    env=cdk.Environment(region="us-east-1", account="222222222222")
)

# Import source table
imported_source = dynamodb.TableV2.from_table_arn(replica_stack, "ImportedSource", "arn:aws:dynamodb:us-east-2:111111111111:table/MyMultiAccountTable")

# Create replica - will issue a warning about missing source permissions
replica = dynamodb.TableV2MultiAccountReplica(replica_stack, "ReplicaTable",
    table_name="MyMultiAccountTable",
    replica_source_table=imported_source,
    global_table_settings_replication_mode=dynamodb.GlobalTableSettingsReplicationMode.ALL
)
java
import software.amazon.awscdk.*;


App app = new App();

Stack replicaStack = Stack.Builder.create(app, "ReplicaStack")
        .env(Environment.builder().region("us-east-1").account("222222222222").build())
        .build();

// Import source table
ITableV2 importedSource = TableV2.fromTableArn(replicaStack, "ImportedSource", "arn:aws:dynamodb:us-east-2:111111111111:table/MyMultiAccountTable");

// Create replica - will issue a warning about missing source permissions
TableV2MultiAccountReplica replica = TableV2MultiAccountReplica.Builder.create(replicaStack, "ReplicaTable")
        .tableName("MyMultiAccountTable")
        .replicaSourceTable(importedSource)
        .globalTableSettingsReplicationMode(GlobalTableSettingsReplicationMode.ALL)
        .build();
csharp
using Amazon.CDK;


var app = new App();

var replicaStack = new Stack(app, "ReplicaStack", new StackProps {
    Env = new Environment { Region = "us-east-1", Account = "222222222222" }
});

// Import source table
var importedSource = TableV2.FromTableArn(replicaStack, "ImportedSource", "arn:aws:dynamodb:us-east-2:111111111111:table/MyMultiAccountTable");

// Create replica - will issue a warning about missing source permissions
var replica = new TableV2MultiAccountReplica(replicaStack, "ReplicaTable", new TableV2MultiAccountReplicaProps {
    TableName = "MyMultiAccountTable",
    ReplicaSourceTable = importedSource,
    GlobalTableSettingsReplicationMode = GlobalTableSettingsReplicationMode.ALL
});
go
import "github.com/aws/aws-cdk-go/awscdk"


app := cdk.NewApp()

replicaStack := cdk.NewStack(app, jsii.String("ReplicaStack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-east-1"),
		Account: jsii.String("222222222222"),
	},
})

// Import source table
importedSource := dynamodb.TableV2_FromTableArn(replicaStack, jsii.String("ImportedSource"), jsii.String("arn:aws:dynamodb:us-east-2:111111111111:table/MyMultiAccountTable"))

// Create replica - will issue a warning about missing source permissions
replica := dynamodb.NewTableV2MultiAccountReplica(replicaStack, jsii.String("ReplicaTable"), &TableV2MultiAccountReplicaProps{
	TableName: jsii.String("MyMultiAccountTable"),
	ReplicaSourceTable: importedSource,
	GlobalTableSettingsReplicationMode: dynamodb.GlobalTableSettingsReplicationMode_ALL,
})

Warning: The replica will emit a warning indicating that you must manually configure permissions on the actual source table.

Then configure permissions on the actual source table using the replica ARN as shown in "Adding Replicas to Existing Tables" above.

Key Considerations ​

  • Multi-account replicas can only be created using the TableV2MultiAccountReplica construct
  • Each replica must be in a separate AWS account and region
  • Only Multi-Region Eventual Consistency (MREC) is supported
  • Resource-based policies must be configured on both source and replica tables before replication begins

Multi-Region Strong Consistency (MRSC) ​

By default, DynamoDB global tables provide eventual consistency across regions. For applications requiring strong consistency across regions, you can configure Multi-Region Strong Consistency (MRSC) using the multiRegionConsistency property.

MRSC global tables can be configured in two ways:

  • Three replicas: Deploy your table across three regions within the same region set
  • Two replicas + one witness: Deploy your table across two regions with a witness region for consensus

Region Sets ​

MRSC global tables must be deployed within the same region set. The supported region sets are:

  • US Region set: us-east-1, us-east-2, us-west-2
  • EU Region set: eu-west-1, eu-west-2, eu-west-3, eu-central-1
  • AP Region set: ap-northeast-1, ap-northeast-2, ap-northeast-3

Three Replicas Configuration ​

ts
import * as cdk from 'aws-cdk-lib';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack', { env: { region: 'us-west-2' } });

const mrscTable = new dynamodb.TableV2(stack, 'MRSCTable', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  multiRegionConsistency: dynamodb.MultiRegionConsistency.STRONG,
  replicas: [
    { region: 'us-east-1' },
    { region: 'us-east-2' },
  ],
});
python
import aws_cdk as cdk


app = cdk.App()
stack = cdk.Stack(app, "Stack", env=cdk.Environment(region="us-west-2"))

mrsc_table = dynamodb.TableV2(stack, "MRSCTable",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    multi_region_consistency=dynamodb.MultiRegionConsistency.STRONG,
    replicas=[dynamodb.ReplicaTableProps(region="us-east-1"), dynamodb.ReplicaTableProps(region="us-east-2")
    ]
)
java
import software.amazon.awscdk.*;


App app = new App();
Stack stack = Stack.Builder.create(app, "Stack").env(Environment.builder().region("us-west-2").build()).build();

TableV2 mrscTable = TableV2.Builder.create(stack, "MRSCTable")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .multiRegionConsistency(MultiRegionConsistency.STRONG)
        .replicas(List.of(ReplicaTableProps.builder().region("us-east-1").build(), ReplicaTableProps.builder().region("us-east-2").build()))
        .build();
csharp
using Amazon.CDK;


var app = new App();
var stack = new Stack(app, "Stack", new StackProps { Env = new Environment { Region = "us-west-2" } });

var mrscTable = new TableV2(stack, "MRSCTable", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    MultiRegionConsistency = MultiRegionConsistency.STRONG,
    Replicas = new [] { new ReplicaTableProps { Region = "us-east-1" }, new ReplicaTableProps { Region = "us-east-2" } }
});
go
import "github.com/aws/aws-cdk-go/awscdk"


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})

mrscTable := dynamodb.NewTableV2(stack, jsii.String("MRSCTable"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	MultiRegionConsistency: dynamodb.MultiRegionConsistency_STRONG,
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-east-1"),
		},
		&ReplicaTableProps{
			Region: jsii.String("us-east-2"),
		},
	},
})

Two Replicas + Witness Configuration ​

ts
import * as cdk from 'aws-cdk-lib';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack', { env: { region: 'us-west-2' } });

const mrscTable = new dynamodb.TableV2(stack, 'MRSCTable', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  multiRegionConsistency: dynamodb.MultiRegionConsistency.STRONG,
  replicas: [
    { region: 'us-east-1' },
  ],
  witnessRegion: 'us-east-2',
});
python
import aws_cdk as cdk


app = cdk.App()
stack = cdk.Stack(app, "Stack", env=cdk.Environment(region="us-west-2"))

mrsc_table = dynamodb.TableV2(stack, "MRSCTable",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    multi_region_consistency=dynamodb.MultiRegionConsistency.STRONG,
    replicas=[dynamodb.ReplicaTableProps(region="us-east-1")
    ],
    witness_region="us-east-2"
)
java
import software.amazon.awscdk.*;


App app = new App();
Stack stack = Stack.Builder.create(app, "Stack").env(Environment.builder().region("us-west-2").build()).build();

TableV2 mrscTable = TableV2.Builder.create(stack, "MRSCTable")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .multiRegionConsistency(MultiRegionConsistency.STRONG)
        .replicas(List.of(ReplicaTableProps.builder().region("us-east-1").build()))
        .witnessRegion("us-east-2")
        .build();
csharp
using Amazon.CDK;


var app = new App();
var stack = new Stack(app, "Stack", new StackProps { Env = new Environment { Region = "us-west-2" } });

var mrscTable = new TableV2(stack, "MRSCTable", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    MultiRegionConsistency = MultiRegionConsistency.STRONG,
    Replicas = new [] { new ReplicaTableProps { Region = "us-east-1" } },
    WitnessRegion = "us-east-2"
});
go
import "github.com/aws/aws-cdk-go/awscdk"


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})

mrscTable := dynamodb.NewTableV2(stack, jsii.String("MRSCTable"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	MultiRegionConsistency: dynamodb.MultiRegionConsistency_STRONG,
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-east-1"),
		},
	},
	WitnessRegion: jsii.String("us-east-2"),
})

Important Considerations ​

  • Witness regions can only be used with MultiRegionConsistency.STRONG. Attempting to specify a witness region with eventual consistency will result in a validation error.
  • Region validation: All regions (primary, replicas, and witness) must be within the same region set.
  • Replica count: When using a witness region, you must have exactly 2 replicas (including the primary). Without a witness region, you must have exactly 3 replicas.
  • Performance: MRSC provides strong consistency but may have higher latency compared to eventual consistency.

Further reading: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/V2globaltables_HowItWorks.html#V2globaltables_HowItWorks.consistency-modes-mrsc

Billing ​

The TableV2 construct can be configured with on-demand or provisioned billing:

  • On-demand - The default option. This is a flexible billing option capable of serving requests without capacity planning. The billing mode will be PAY_PER_REQUEST.
  • You can optionally specify the maxReadRequestUnits or maxWriteRequestUnits on individual tables and associated global secondary indexes (GSIs). When you configure maximum throughput for an on-demand table, throughput requests that exceed the maximum amount specified will be throttled.
  • Provisioned - Specify the readCapacity and writeCapacity that you need for your application. The billing mode will be PROVISIONED. Capacity can be configured using one of the following modes:
    • Fixed - provisioned throughput capacity is configured with a fixed number of I/O operations per second.
    • Autoscaled - provisioned throughput capacity is dynamically adjusted on your behalf in response to actual traffic patterns.

Note: writeCapacity can only be configured using autoscaled capacity.

The following example shows how to configure TableV2 with on-demand billing:

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  billing: dynamodb.Billing.onDemand(),
})
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    billing=dynamodb.Billing.on_demand()
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .billing(Billing.onDemand())
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    Billing = Billing.OnDemand()
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	Billing: dynamodb.Billing_OnDemand(),
})

The following example shows how to configure TableV2 with on-demand billing with optional maximum throughput configured:

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  billing: dynamodb.Billing.onDemand({
    maxReadRequestUnits: 100,
    maxWriteRequestUnits: 115,
  }),
})
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    billing=dynamodb.Billing.on_demand(
        max_read_request_units=100,
        max_write_request_units=115
    )
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .billing(Billing.onDemand(MaxThroughputProps.builder()
                .maxReadRequestUnits(100)
                .maxWriteRequestUnits(115)
                .build()))
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    Billing = Billing.OnDemand(new MaxThroughputProps {
        MaxReadRequestUnits = 100,
        MaxWriteRequestUnits = 115
    })
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	Billing: dynamodb.Billing_OnDemand(&MaxThroughputProps{
		MaxReadRequestUnits: jsii.Number(100),
		MaxWriteRequestUnits: jsii.Number(115),
	}),
})

When using provisioned billing, you must also specify readCapacity and writeCapacity. You can choose to configure readCapacity with fixed capacity or autoscaled capacity, but writeCapacity can only be configured with autoscaled capacity. The following example shows how to configure TableV2 with provisioned billing:

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  billing: dynamodb.Billing.provisioned({
    readCapacity: dynamodb.Capacity.fixed(10),
    writeCapacity: dynamodb.Capacity.autoscaled({ maxCapacity: 15 }),
  }),
});
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    billing=dynamodb.Billing.provisioned(
        read_capacity=dynamodb.Capacity.fixed(10),
        write_capacity=dynamodb.Capacity.autoscaled(max_capacity=15)
    )
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .billing(Billing.provisioned(ThroughputProps.builder()
                .readCapacity(Capacity.fixed(10))
                .writeCapacity(Capacity.autoscaled(AutoscaledCapacityOptions.builder().maxCapacity(15).build()))
                .build()))
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    Billing = Billing.Provisioned(new ThroughputProps {
        ReadCapacity = Capacity.Fixed(10),
        WriteCapacity = Capacity.Autoscaled(new AutoscaledCapacityOptions { MaxCapacity = 15 })
    })
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	Billing: dynamodb.Billing_Provisioned(&ThroughputProps{
		ReadCapacity: dynamodb.Capacity_Fixed(jsii.Number(10)),
		WriteCapacity: dynamodb.Capacity_Autoscaled(&AutoscaledCapacityOptions{
			MaxCapacity: jsii.Number(15),
		}),
	}),
})

When using provisioned billing, you can configure the readCapacity on a per-replica basis:

ts
import * as cdk from 'aws-cdk-lib';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack', { env: { region: 'us-west-2' } });

const globalTable = new dynamodb.TableV2(stack, 'GlobalTable', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  billing: dynamodb.Billing.provisioned({
    readCapacity: dynamodb.Capacity.fixed(10),
    writeCapacity: dynamodb.Capacity.autoscaled({ maxCapacity: 15 }),
  }),
  replicas: [
    {
      region: 'us-east-1',
    },
    {
      region: 'us-east-2',
      readCapacity: dynamodb.Capacity.autoscaled({ maxCapacity: 20, targetUtilizationPercent: 50 }),
    },
  ],
});
python
import aws_cdk as cdk


app = cdk.App()
stack = cdk.Stack(app, "Stack", env=cdk.Environment(region="us-west-2"))

global_table = dynamodb.TableV2(stack, "GlobalTable",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    billing=dynamodb.Billing.provisioned(
        read_capacity=dynamodb.Capacity.fixed(10),
        write_capacity=dynamodb.Capacity.autoscaled(max_capacity=15)
    ),
    replicas=[dynamodb.ReplicaTableProps(
        region="us-east-1"
    ), dynamodb.ReplicaTableProps(
        region="us-east-2",
        read_capacity=dynamodb.Capacity.autoscaled(max_capacity=20, target_utilization_percent=50)
    )
    ]
)
java
import software.amazon.awscdk.*;


App app = new App();
Stack stack = Stack.Builder.create(app, "Stack").env(Environment.builder().region("us-west-2").build()).build();

TableV2 globalTable = TableV2.Builder.create(stack, "GlobalTable")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .billing(Billing.provisioned(ThroughputProps.builder()
                .readCapacity(Capacity.fixed(10))
                .writeCapacity(Capacity.autoscaled(AutoscaledCapacityOptions.builder().maxCapacity(15).build()))
                .build()))
        .replicas(List.of(ReplicaTableProps.builder()
                .region("us-east-1")
                .build(), ReplicaTableProps.builder()
                .region("us-east-2")
                .readCapacity(Capacity.autoscaled(AutoscaledCapacityOptions.builder().maxCapacity(20).targetUtilizationPercent(50).build()))
                .build()))
        .build();
csharp
using Amazon.CDK;


var app = new App();
var stack = new Stack(app, "Stack", new StackProps { Env = new Environment { Region = "us-west-2" } });

var globalTable = new TableV2(stack, "GlobalTable", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    Billing = Billing.Provisioned(new ThroughputProps {
        ReadCapacity = Capacity.Fixed(10),
        WriteCapacity = Capacity.Autoscaled(new AutoscaledCapacityOptions { MaxCapacity = 15 })
    }),
    Replicas = new [] { new ReplicaTableProps {
        Region = "us-east-1"
    }, new ReplicaTableProps {
        Region = "us-east-2",
        ReadCapacity = Capacity.Autoscaled(new AutoscaledCapacityOptions { MaxCapacity = 20, TargetUtilizationPercent = 50 })
    } }
});
go
import "github.com/aws/aws-cdk-go/awscdk"


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})

globalTable := dynamodb.NewTableV2(stack, jsii.String("GlobalTable"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	Billing: dynamodb.Billing_Provisioned(&ThroughputProps{
		ReadCapacity: dynamodb.Capacity_Fixed(jsii.Number(10)),
		WriteCapacity: dynamodb.Capacity_Autoscaled(&AutoscaledCapacityOptions{
			MaxCapacity: jsii.Number(15),
		}),
	}),
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-east-1"),
		},
		&ReplicaTableProps{
			Region: jsii.String("us-east-2"),
			ReadCapacity: dynamodb.Capacity_*Autoscaled(&AutoscaledCapacityOptions{
				MaxCapacity: jsii.Number(20),
				TargetUtilizationPercent: jsii.Number(50),
			}),
		},
	},
})

When changing the billing for a table from provisioned to on-demand or from on-demand to provisioned, seedCapacity must be configured for each autoscaled resource:

ts
const globalTable = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  billing: dynamodb.Billing.provisioned({
    readCapacity: dynamodb.Capacity.fixed(10),
    writeCapacity: dynamodb.Capacity.autoscaled({ maxCapacity: 10, seedCapacity: 20 }),
  }),
});
python
global_table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    billing=dynamodb.Billing.provisioned(
        read_capacity=dynamodb.Capacity.fixed(10),
        write_capacity=dynamodb.Capacity.autoscaled(max_capacity=10, seed_capacity=20)
    )
)
java
TableV2 globalTable = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .billing(Billing.provisioned(ThroughputProps.builder()
                .readCapacity(Capacity.fixed(10))
                .writeCapacity(Capacity.autoscaled(AutoscaledCapacityOptions.builder().maxCapacity(10).seedCapacity(20).build()))
                .build()))
        .build();
csharp
var globalTable = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    Billing = Billing.Provisioned(new ThroughputProps {
        ReadCapacity = Capacity.Fixed(10),
        WriteCapacity = Capacity.Autoscaled(new AutoscaledCapacityOptions { MaxCapacity = 10, SeedCapacity = 20 })
    })
});
go
globalTable := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	Billing: dynamodb.Billing_Provisioned(&ThroughputProps{
		ReadCapacity: dynamodb.Capacity_Fixed(jsii.Number(10)),
		WriteCapacity: dynamodb.Capacity_Autoscaled(&AutoscaledCapacityOptions{
			MaxCapacity: jsii.Number(10),
			SeedCapacity: jsii.Number(20),
		}),
	}),
})

Further reading: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html

Warm Throughput ​

Warm throughput refers to the number of read and write operations your DynamoDB table can instantaneously support.

This optional configuration allows you to pre-warm your table or index to handle anticipated throughput, ensuring optimal performance under expected load.

The Warm Throughput configuration settings are automatically replicated across all Global Table replicas.

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
  warmThroughput: {
      readUnitsPerSecond: 15000,
      writeUnitsPerSecond: 20000,
    },
});
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="id", type=dynamodb.AttributeType.STRING),
    warm_throughput=dynamodb.WarmThroughput(
        read_units_per_second=15000,
        write_units_per_second=20000
    )
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("id").type(AttributeType.STRING).build())
        .warmThroughput(WarmThroughput.builder()
                .readUnitsPerSecond(15000)
                .writeUnitsPerSecond(20000)
                .build())
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "id", Type = AttributeType.STRING },
    WarmThroughput = new WarmThroughput {
        ReadUnitsPerSecond = 15000,
        WriteUnitsPerSecond = 20000
    }
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("id"),
		Type: dynamodb.AttributeType_STRING,
	},
	WarmThroughput: &WarmThroughput{
		ReadUnitsPerSecond: jsii.Number(15000),
		WriteUnitsPerSecond: jsii.Number(20000),
	},
})

Further reading: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/warm-throughput.html

Encryption ​

All user data stored in a DynamoDB table is fully encrypted at rest. When creating an instance of the TableV2 construct, you can select the following table encryption options:

  • AWS owned keys - Default encryption type. The keys are owned by DynamoDB (no additional charge).
  • AWS managed keys - The keys are stored in your account and are managed by AWS KMS (AWS KMS charges apply).
  • Customer managed keys - The keys are stored in your account and are created, owned, and managed by you. You have full control over the KMS keys (AWS KMS charges apply).

The following is an example of how to configure TableV2 with encryption using an AWS owned key:

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  encryption: dynamodb.TableEncryptionV2.dynamoOwnedKey(),
})
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    encryption=dynamodb.TableEncryptionV2.dynamo_owned_key()
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .encryption(TableEncryptionV2.dynamoOwnedKey())
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    Encryption = TableEncryptionV2.DynamoOwnedKey()
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	Encryption: dynamodb.TableEncryptionV2_DynamoOwnedKey(),
})

The following is an example of how to configure TableV2 with encryption using an AWS managed key:

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  encryption: dynamodb.TableEncryptionV2.awsManagedKey(),
})
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    encryption=dynamodb.TableEncryptionV2.aws_managed_key()
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .encryption(TableEncryptionV2.awsManagedKey())
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    Encryption = TableEncryptionV2.AwsManagedKey()
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	Encryption: dynamodb.TableEncryptionV2_AwsManagedKey(),
})

When configuring TableV2 with encryption using customer managed keys, you must specify the KMS key for the primary table as the tableKey. A map of replicaKeyArns must be provided containing each replica region and the associated KMS key ARN:

ts
import * as cdk from 'aws-cdk-lib';
import * as kms from 'aws-cdk-lib/aws-kms';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack', { env: { region: 'us-west-2' } });

const tableKey = new kms.Key(stack, 'Key');
const replicaKeyArns = {
  'us-east-1': 'arn:aws:kms:us-east-1:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6',
  'us-east-2': 'arn:aws:kms:us-east-2:123456789012:key/h90bkasj-bs1j-92wp-s2ka-bh857d60bkj8',
};

const globalTable = new dynamodb.TableV2(stack, 'GlobalTable', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  encryption: dynamodb.TableEncryptionV2.customerManagedKey(tableKey, replicaKeyArns),
  replicas: [
    { region: 'us-east-1' },
    { region: 'us-east-2' },
  ],
});
python
import aws_cdk as cdk
import aws_cdk.aws_kms as kms


app = cdk.App()
stack = cdk.Stack(app, "Stack", env=cdk.Environment(region="us-west-2"))

table_key = kms.Key(stack, "Key")
replica_key_arns = {
    "us-east-1": "arn:aws:kms:us-east-1:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6",
    "us-east-2": "arn:aws:kms:us-east-2:123456789012:key/h90bkasj-bs1j-92wp-s2ka-bh857d60bkj8"
}

global_table = dynamodb.TableV2(stack, "GlobalTable",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    encryption=dynamodb.TableEncryptionV2.customer_managed_key(table_key, replica_key_arns),
    replicas=[dynamodb.ReplicaTableProps(region="us-east-1"), dynamodb.ReplicaTableProps(region="us-east-2")
    ]
)
java
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.kms.*;


App app = new App();
Stack stack = Stack.Builder.create(app, "Stack").env(Environment.builder().region("us-west-2").build()).build();

Key tableKey = new Key(stack, "Key");
Map<String, String> replicaKeyArns = Map.of(
        "us-east-1", "arn:aws:kms:us-east-1:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6",
        "us-east-2", "arn:aws:kms:us-east-2:123456789012:key/h90bkasj-bs1j-92wp-s2ka-bh857d60bkj8");

TableV2 globalTable = TableV2.Builder.create(stack, "GlobalTable")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .encryption(TableEncryptionV2.customerManagedKey(tableKey, replicaKeyArns))
        .replicas(List.of(ReplicaTableProps.builder().region("us-east-1").build(), ReplicaTableProps.builder().region("us-east-2").build()))
        .build();
csharp
using Amazon.CDK;
using Amazon.CDK.AWS.KMS;


var app = new App();
var stack = new Stack(app, "Stack", new StackProps { Env = new Environment { Region = "us-west-2" } });

var tableKey = new Key(stack, "Key");
IDictionary<string, string> replicaKeyArns = new Dictionary<string, string> {
    { "us-east-1", "arn:aws:kms:us-east-1:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6" },
    { "us-east-2", "arn:aws:kms:us-east-2:123456789012:key/h90bkasj-bs1j-92wp-s2ka-bh857d60bkj8" }
};

var globalTable = new TableV2(stack, "GlobalTable", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    Encryption = TableEncryptionV2.CustomerManagedKey(tableKey, replicaKeyArns),
    Replicas = new [] { new ReplicaTableProps { Region = "us-east-1" }, new ReplicaTableProps { Region = "us-east-2" } }
});
go
import "github.com/aws/aws-cdk-go/awscdk"
import kms "github.com/aws/aws-cdk-go/awscdk"


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})

tableKey := kms.NewKey(stack, jsii.String("Key"))
replicaKeyArns := map[string]*string{
	"us-east-1": jsii.String("arn:aws:kms:us-east-1:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6"),
	"us-east-2": jsii.String("arn:aws:kms:us-east-2:123456789012:key/h90bkasj-bs1j-92wp-s2ka-bh857d60bkj8"),
}

globalTable := dynamodb.NewTableV2(stack, jsii.String("GlobalTable"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	Encryption: dynamodb.TableEncryptionV2_CustomerManagedKey(tableKey, replicaKeyArns),
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-east-1"),
		},
		&ReplicaTableProps{
			Region: jsii.String("us-east-2"),
		},
	},
})

Note: When encryption is configured with customer managed keys, you must have a key already created in each replica region.

Further reading: https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-mgmt

Secondary Indexes ​

Secondary indexes allow efficient access to data with attributes other than the primaryKey. DynamoDB supports two types of secondary indexes:

  • Global secondary index - An index with partition key(s) and optional sort key(s) that can be different from those on the base table. A globalSecondaryIndex is considered "global" because queries on the index can span all of the data in the base table, across all partitions. A globalSecondaryIndex is stored in its own partition space away from the base table and scales separately from the base table.

  • Local secondary index - An index that has the same partitionKey as the base table, but a different sortKey. A localSecondaryIndex is "local" in the sense that every partition of a localSecondaryIndex is scoped to a base table partition that has the same partitionKey value.

Further reading: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html

Global Secondary Indexes ​

TableV2 can be configured with globalSecondaryIndexes by providing them as a TableV2 property:

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  globalSecondaryIndexes: [
    {
      indexName: 'gsi',
      partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
    },
  ],
});
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    global_secondary_indexes=[dynamodb.GlobalSecondaryIndexPropsV2(
        index_name="gsi",
        partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING)
    )
    ]
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .globalSecondaryIndexes(List.of(GlobalSecondaryIndexPropsV2.builder()
                .indexName("gsi")
                .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
                .build()))
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    GlobalSecondaryIndexes = new [] { new GlobalSecondaryIndexPropsV2 {
        IndexName = "gsi",
        PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING }
    } }
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	GlobalSecondaryIndexes: []GlobalSecondaryIndexPropsV2{
		&GlobalSecondaryIndexPropsV2{
			IndexName: jsii.String("gsi"),
			PartitionKey: &Attribute{
				Name: jsii.String("pk"),
				Type: dynamodb.AttributeType_STRING,
			},
		},
	},
})

Multi-attribute Keys ​

Global secondary indexes support multi-attribute keys, allowing you to specify multiple partition keys and/or multiple sort keys. This enables more flexible query patterns for complex data models.

Key Constraints:

  • You can specify up to 4 partition keys per global secondary index
  • You can specify up to 4 sort keys per global secondary index
  • Use either partitionKey (singular) or partitionKeys (plural), but not both
  • Use either sortKey (singular) or sortKeys (plural), but not both
  • At least one partition key must be specified (either partitionKey or partitionKeys)
  • For multiple keys, you must use the plural parameters (partitionKeys and/or sortKeys)
  • Keys cannot be added or modified after index creation - attempting to add additional keys to an existing index will result in an error

Example with multi-attribute partition and sort keys:

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  globalSecondaryIndexes: [
    {
      indexName: 'multi-attribute-gsi',
      partitionKeys: [
        { name: 'gsi_pk1', type: dynamodb.AttributeType.STRING },
        { name: 'gsi_pk2', type: dynamodb.AttributeType.NUMBER },
      ],
      sortKeys: [
        { name: 'gsi_sk1', type: dynamodb.AttributeType.STRING },
        { name: 'gsi_sk2', type: dynamodb.AttributeType.BINARY },
      ],
    },
  ],
});
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    global_secondary_indexes=[dynamodb.GlobalSecondaryIndexPropsV2(
        index_name="multi-attribute-gsi",
        partition_keys=[dynamodb.Attribute(name="gsi_pk1", type=dynamodb.AttributeType.STRING), dynamodb.Attribute(name="gsi_pk2", type=dynamodb.AttributeType.NUMBER)
        ],
        sort_keys=[dynamodb.Attribute(name="gsi_sk1", type=dynamodb.AttributeType.STRING), dynamodb.Attribute(name="gsi_sk2", type=dynamodb.AttributeType.BINARY)
        ]
    )
    ]
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .globalSecondaryIndexes(List.of(GlobalSecondaryIndexPropsV2.builder()
                .indexName("multi-attribute-gsi")
                .partitionKeys(List.of(Attribute.builder().name("gsi_pk1").type(AttributeType.STRING).build(), Attribute.builder().name("gsi_pk2").type(AttributeType.NUMBER).build()))
                .sortKeys(List.of(Attribute.builder().name("gsi_sk1").type(AttributeType.STRING).build(), Attribute.builder().name("gsi_sk2").type(AttributeType.BINARY).build()))
                .build()))
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    GlobalSecondaryIndexes = new [] { new GlobalSecondaryIndexPropsV2 {
        IndexName = "multi-attribute-gsi",
        PartitionKeys = new [] { new Attribute { Name = "gsi_pk1", Type = AttributeType.STRING }, new Attribute { Name = "gsi_pk2", Type = AttributeType.NUMBER } },
        SortKeys = new [] { new Attribute { Name = "gsi_sk1", Type = AttributeType.STRING }, new Attribute { Name = "gsi_sk2", Type = AttributeType.BINARY } }
    } }
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	GlobalSecondaryIndexes: []GlobalSecondaryIndexPropsV2{
		&GlobalSecondaryIndexPropsV2{
			IndexName: jsii.String("multi-attribute-gsi"),
			PartitionKeys: []Attribute{
				&Attribute{
					Name: jsii.String("gsi_pk1"),
					Type: dynamodb.AttributeType_STRING,
				},
				&Attribute{
					Name: jsii.String("gsi_pk2"),
					Type: dynamodb.AttributeType_NUMBER,
				},
			},
			SortKeys: []Attribute{
				&Attribute{
					Name: jsii.String("gsi_sk1"),
					Type: dynamodb.AttributeType_STRING,
				},
				&Attribute{
					Name: jsii.String("gsi_sk2"),
					Type: dynamodb.AttributeType_BINARY,
				},
			},
		},
	},
})

You can also add a globalSecondaryIndex using the addGlobalSecondaryIndex method:

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  globalSecondaryIndexes: [
    {
      indexName: 'gsi1',
      partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
    },
  ],
});

table.addGlobalSecondaryIndex({
  indexName: 'gsi2',
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
});

// Add a GSI with multi-attribute keys
table.addGlobalSecondaryIndex({
  indexName: 'multi-attribute-gsi2',
  partitionKeys: [
    { name: 'multi-attribute_pk1', type: dynamodb.AttributeType.STRING },
    { name: 'multi-attribute_pk2', type: dynamodb.AttributeType.NUMBER },
  ],
  sortKey: { name: 'sk', type: dynamodb.AttributeType.STRING },
});
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    global_secondary_indexes=[dynamodb.GlobalSecondaryIndexPropsV2(
        index_name="gsi1",
        partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING)
    )
    ]
)

table.add_global_secondary_index(
    index_name="gsi2",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING)
)

# Add a GSI with multi-attribute keys
table.add_global_secondary_index(
    index_name="multi-attribute-gsi2",
    partition_keys=[dynamodb.Attribute(name="multi-attribute_pk1", type=dynamodb.AttributeType.STRING), dynamodb.Attribute(name="multi-attribute_pk2", type=dynamodb.AttributeType.NUMBER)
    ],
    sort_key=dynamodb.Attribute(name="sk", type=dynamodb.AttributeType.STRING)
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .globalSecondaryIndexes(List.of(GlobalSecondaryIndexPropsV2.builder()
                .indexName("gsi1")
                .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
                .build()))
        .build();

table.addGlobalSecondaryIndex(GlobalSecondaryIndexPropsV2.builder()
        .indexName("gsi2")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .build());

// Add a GSI with multi-attribute keys
table.addGlobalSecondaryIndex(GlobalSecondaryIndexPropsV2.builder()
        .indexName("multi-attribute-gsi2")
        .partitionKeys(List.of(Attribute.builder().name("multi-attribute_pk1").type(AttributeType.STRING).build(), Attribute.builder().name("multi-attribute_pk2").type(AttributeType.NUMBER).build()))
        .sortKey(Attribute.builder().name("sk").type(AttributeType.STRING).build())
        .build());
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    GlobalSecondaryIndexes = new [] { new GlobalSecondaryIndexPropsV2 {
        IndexName = "gsi1",
        PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING }
    } }
});

table.AddGlobalSecondaryIndex(new GlobalSecondaryIndexPropsV2 {
    IndexName = "gsi2",
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING }
});

// Add a GSI with multi-attribute keys
table.AddGlobalSecondaryIndex(new GlobalSecondaryIndexPropsV2 {
    IndexName = "multi-attribute-gsi2",
    PartitionKeys = new [] { new Attribute { Name = "multi-attribute_pk1", Type = AttributeType.STRING }, new Attribute { Name = "multi-attribute_pk2", Type = AttributeType.NUMBER } },
    SortKey = new Attribute { Name = "sk", Type = AttributeType.STRING }
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	GlobalSecondaryIndexes: []GlobalSecondaryIndexPropsV2{
		&GlobalSecondaryIndexPropsV2{
			IndexName: jsii.String("gsi1"),
			PartitionKey: &Attribute{
				Name: jsii.String("pk"),
				Type: dynamodb.AttributeType_STRING,
			},
		},
	},
})

table.AddGlobalSecondaryIndex(&GlobalSecondaryIndexPropsV2{
	IndexName: jsii.String("gsi2"),
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
})

// Add a GSI with multi-attribute keys
table.AddGlobalSecondaryIndex(&GlobalSecondaryIndexPropsV2{
	IndexName: jsii.String("multi-attribute-gsi2"),
	PartitionKeys: []Attribute{
		&Attribute{
			Name: jsii.String("multi-attribute_pk1"),
			Type: dynamodb.AttributeType_STRING,
		},
		&Attribute{
			Name: jsii.String("multi-attribute_pk2"),
			Type: dynamodb.AttributeType_NUMBER,
		},
	},
	SortKey: &Attribute{
		Name: jsii.String("sk"),
		Type: dynamodb.AttributeType_STRING,
	},
})

You can configure readCapacity and writeCapacity on a globalSecondaryIndex when an TableV2 is configured with provisioned billing. If TableV2 is configured with provisioned billing but readCapacity or writeCapacity are not configured on a globalSecondaryIndex, then they will be inherited from the capacity settings specified with the billing configuration:

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  billing: dynamodb.Billing.provisioned({
    readCapacity: dynamodb.Capacity.fixed(10),
    writeCapacity: dynamodb.Capacity.autoscaled({ maxCapacity: 10 }),
  }),
  globalSecondaryIndexes: [
    {
      indexName: 'gsi1',
      partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
      readCapacity: dynamodb.Capacity.fixed(15),
      // write capacity inherited from billing - dynamodb.Capacity.autoscaled({ maxCapacity: 10 })
    },
    {
      indexName: 'gsi2',
      partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
      writeCapacity: dynamodb.Capacity.autoscaled({ minCapacity: 5, maxCapacity: 20 }),
      // read capacity inherited from billing - dynamodb.Capacity.fixed(10)
    },
  ],
});
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    billing=dynamodb.Billing.provisioned(
        read_capacity=dynamodb.Capacity.fixed(10),
        write_capacity=dynamodb.Capacity.autoscaled(max_capacity=10)
    ),
    global_secondary_indexes=[dynamodb.GlobalSecondaryIndexPropsV2(
        index_name="gsi1",
        partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
        read_capacity=dynamodb.Capacity.fixed(15)
    ), dynamodb.GlobalSecondaryIndexPropsV2(
        index_name="gsi2",
        partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
        write_capacity=dynamodb.Capacity.autoscaled(min_capacity=5, max_capacity=20)
    )
    ]
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .billing(Billing.provisioned(ThroughputProps.builder()
                .readCapacity(Capacity.fixed(10))
                .writeCapacity(Capacity.autoscaled(AutoscaledCapacityOptions.builder().maxCapacity(10).build()))
                .build()))
        .globalSecondaryIndexes(List.of(GlobalSecondaryIndexPropsV2.builder()
                .indexName("gsi1")
                .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
                .readCapacity(Capacity.fixed(15))
                .build(), GlobalSecondaryIndexPropsV2.builder()
                .indexName("gsi2")
                .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
                .writeCapacity(Capacity.autoscaled(AutoscaledCapacityOptions.builder().minCapacity(5).maxCapacity(20).build()))
                .build()))
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    Billing = Billing.Provisioned(new ThroughputProps {
        ReadCapacity = Capacity.Fixed(10),
        WriteCapacity = Capacity.Autoscaled(new AutoscaledCapacityOptions { MaxCapacity = 10 })
    }),
    GlobalSecondaryIndexes = new [] { new GlobalSecondaryIndexPropsV2 {
        IndexName = "gsi1",
        PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
        ReadCapacity = Capacity.Fixed(15)
    }, new GlobalSecondaryIndexPropsV2 {
        IndexName = "gsi2",
        PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
        WriteCapacity = Capacity.Autoscaled(new AutoscaledCapacityOptions { MinCapacity = 5, MaxCapacity = 20 })
    } }
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	Billing: dynamodb.Billing_Provisioned(&ThroughputProps{
		ReadCapacity: dynamodb.Capacity_Fixed(jsii.Number(10)),
		WriteCapacity: dynamodb.Capacity_Autoscaled(&AutoscaledCapacityOptions{
			MaxCapacity: jsii.Number(10),
		}),
	}),
	GlobalSecondaryIndexes: []GlobalSecondaryIndexPropsV2{
		&GlobalSecondaryIndexPropsV2{
			IndexName: jsii.String("gsi1"),
			PartitionKey: &Attribute{
				Name: jsii.String("pk"),
				Type: dynamodb.AttributeType_STRING,
			},
			ReadCapacity: dynamodb.Capacity_*Fixed(jsii.Number(15)),
		},
		&GlobalSecondaryIndexPropsV2{
			IndexName: jsii.String("gsi2"),
			PartitionKey: &Attribute{
				Name: jsii.String("pk"),
				Type: dynamodb.AttributeType_STRING,
			},
			WriteCapacity: dynamodb.Capacity_*Autoscaled(&AutoscaledCapacityOptions{
				MinCapacity: jsii.Number(5),
				MaxCapacity: jsii.Number(20),
			}),
		},
	},
})

All globalSecondaryIndexes for replica tables are inherited from the primary table. You can configure contributorInsightsSpecification and readCapacity for each globalSecondaryIndex on a per-replica basis:

ts
import * as cdk from 'aws-cdk-lib';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack', { env: { region: 'us-west-2' } });

const globalTable = new dynamodb.TableV2(stack, 'GlobalTable', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  contributorInsightsSpecification: {
    enabled: true,
  },
  billing: dynamodb.Billing.provisioned({
    readCapacity: dynamodb.Capacity.fixed(10),
    writeCapacity: dynamodb.Capacity.autoscaled({ maxCapacity: 10 }),
  }),
  // each global secondary index will inherit contributor insights as true
  globalSecondaryIndexes: [
    {
      indexName: 'gsi1',
      partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
      readCapacity: dynamodb.Capacity.fixed(15),
    },
    {
      indexName: 'gsi2',
      partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
      writeCapacity: dynamodb.Capacity.autoscaled({ minCapacity: 5, maxCapacity: 20 }),
    },
  ],
  replicas: [
    {
      region: 'us-east-1',
      globalSecondaryIndexOptions: {
        gsi1: {
          readCapacity: dynamodb.Capacity.autoscaled({ minCapacity: 1, maxCapacity: 10 })
        },
      },
    },
    {
      region: 'us-east-2',
      globalSecondaryIndexOptions: {
        gsi2: {
          contributorInsightsSpecification: {
            enabled: false,
          },
        },
      },
    },
  ],
});
python
import aws_cdk as cdk


app = cdk.App()
stack = cdk.Stack(app, "Stack", env=cdk.Environment(region="us-west-2"))

global_table = dynamodb.TableV2(stack, "GlobalTable",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    contributor_insights_specification=dynamodb.ContributorInsightsSpecification(
        enabled=True
    ),
    billing=dynamodb.Billing.provisioned(
        read_capacity=dynamodb.Capacity.fixed(10),
        write_capacity=dynamodb.Capacity.autoscaled(max_capacity=10)
    ),
    # each global secondary index will inherit contributor insights as true
    global_secondary_indexes=[dynamodb.GlobalSecondaryIndexPropsV2(
        index_name="gsi1",
        partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
        read_capacity=dynamodb.Capacity.fixed(15)
    ), dynamodb.GlobalSecondaryIndexPropsV2(
        index_name="gsi2",
        partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
        write_capacity=dynamodb.Capacity.autoscaled(min_capacity=5, max_capacity=20)
    )
    ],
    replicas=[dynamodb.ReplicaTableProps(
        region="us-east-1",
        global_secondary_index_options={
            "gsi1": dynamodb.ReplicaGlobalSecondaryIndexOptions(
                read_capacity=dynamodb.Capacity.autoscaled(min_capacity=1, max_capacity=10)
            )
        }
    ), dynamodb.ReplicaTableProps(
        region="us-east-2",
        global_secondary_index_options={
            "gsi2": dynamodb.ReplicaGlobalSecondaryIndexOptions(
                contributor_insights_specification=dynamodb.ContributorInsightsSpecification(
                    enabled=False
                )
            )
        }
    )
    ]
)
java
import software.amazon.awscdk.*;


App app = new App();
Stack stack = Stack.Builder.create(app, "Stack").env(Environment.builder().region("us-west-2").build()).build();

TableV2 globalTable = TableV2.Builder.create(stack, "GlobalTable")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .contributorInsightsSpecification(ContributorInsightsSpecification.builder()
                .enabled(true)
                .build())
        .billing(Billing.provisioned(ThroughputProps.builder()
                .readCapacity(Capacity.fixed(10))
                .writeCapacity(Capacity.autoscaled(AutoscaledCapacityOptions.builder().maxCapacity(10).build()))
                .build()))
        // each global secondary index will inherit contributor insights as true
        .globalSecondaryIndexes(List.of(GlobalSecondaryIndexPropsV2.builder()
                .indexName("gsi1")
                .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
                .readCapacity(Capacity.fixed(15))
                .build(), GlobalSecondaryIndexPropsV2.builder()
                .indexName("gsi2")
                .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
                .writeCapacity(Capacity.autoscaled(AutoscaledCapacityOptions.builder().minCapacity(5).maxCapacity(20).build()))
                .build()))
        .replicas(List.of(ReplicaTableProps.builder()
                .region("us-east-1")
                .globalSecondaryIndexOptions(Map.of(
                        "gsi1", ReplicaGlobalSecondaryIndexOptions.builder()
                                .readCapacity(Capacity.autoscaled(AutoscaledCapacityOptions.builder().minCapacity(1).maxCapacity(10).build()))
                                .build()))
                .build(), ReplicaTableProps.builder()
                .region("us-east-2")
                .globalSecondaryIndexOptions(Map.of(
                        "gsi2", ReplicaGlobalSecondaryIndexOptions.builder()
                                .contributorInsightsSpecification(ContributorInsightsSpecification.builder()
                                        .enabled(false)
                                        .build())
                                .build()))
                .build()))
        .build();
csharp
using Amazon.CDK;


var app = new App();
var stack = new Stack(app, "Stack", new StackProps { Env = new Environment { Region = "us-west-2" } });

var globalTable = new TableV2(stack, "GlobalTable", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    ContributorInsightsSpecification = new ContributorInsightsSpecification {
        Enabled = true
    },
    Billing = Billing.Provisioned(new ThroughputProps {
        ReadCapacity = Capacity.Fixed(10),
        WriteCapacity = Capacity.Autoscaled(new AutoscaledCapacityOptions { MaxCapacity = 10 })
    }),
    // each global secondary index will inherit contributor insights as true
    GlobalSecondaryIndexes = new [] { new GlobalSecondaryIndexPropsV2 {
        IndexName = "gsi1",
        PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
        ReadCapacity = Capacity.Fixed(15)
    }, new GlobalSecondaryIndexPropsV2 {
        IndexName = "gsi2",
        PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
        WriteCapacity = Capacity.Autoscaled(new AutoscaledCapacityOptions { MinCapacity = 5, MaxCapacity = 20 })
    } },
    Replicas = new [] { new ReplicaTableProps {
        Region = "us-east-1",
        GlobalSecondaryIndexOptions = new Dictionary<string, ReplicaGlobalSecondaryIndexOptions> {
            { "gsi1", new ReplicaGlobalSecondaryIndexOptions {
                ReadCapacity = Capacity.Autoscaled(new AutoscaledCapacityOptions { MinCapacity = 1, MaxCapacity = 10 })
            } }
        }
    }, new ReplicaTableProps {
        Region = "us-east-2",
        GlobalSecondaryIndexOptions = new Dictionary<string, ReplicaGlobalSecondaryIndexOptions> {
            { "gsi2", new ReplicaGlobalSecondaryIndexOptions {
                ContributorInsightsSpecification = new ContributorInsightsSpecification {
                    Enabled = false
                }
            } }
        }
    } }
});
go
import "github.com/aws/aws-cdk-go/awscdk"


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})

globalTable := dynamodb.NewTableV2(stack, jsii.String("GlobalTable"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	ContributorInsightsSpecification: &ContributorInsightsSpecification{
		Enabled: jsii.Boolean(true),
	},
	Billing: dynamodb.Billing_Provisioned(&ThroughputProps{
		ReadCapacity: dynamodb.Capacity_Fixed(jsii.Number(10)),
		WriteCapacity: dynamodb.Capacity_Autoscaled(&AutoscaledCapacityOptions{
			MaxCapacity: jsii.Number(10),
		}),
	}),
	// each global secondary index will inherit contributor insights as true
	GlobalSecondaryIndexes: []GlobalSecondaryIndexPropsV2{
		&GlobalSecondaryIndexPropsV2{
			IndexName: jsii.String("gsi1"),
			PartitionKey: &Attribute{
				Name: jsii.String("pk"),
				Type: dynamodb.AttributeType_STRING,
			},
			ReadCapacity: dynamodb.Capacity_*Fixed(jsii.Number(15)),
		},
		&GlobalSecondaryIndexPropsV2{
			IndexName: jsii.String("gsi2"),
			PartitionKey: &Attribute{
				Name: jsii.String("pk"),
				Type: dynamodb.AttributeType_STRING,
			},
			WriteCapacity: dynamodb.Capacity_*Autoscaled(&AutoscaledCapacityOptions{
				MinCapacity: jsii.Number(5),
				MaxCapacity: jsii.Number(20),
			}),
		},
	},
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-east-1"),
			GlobalSecondaryIndexOptions: map[string]ReplicaGlobalSecondaryIndexOptions{
				"gsi1": &ReplicaGlobalSecondaryIndexOptions{
					"readCapacity": dynamodb.Capacity_*Autoscaled(&AutoscaledCapacityOptions{
						"minCapacity": jsii.Number(1),
						"maxCapacity": jsii.Number(10),
					}),
				},
			},
		},
		&ReplicaTableProps{
			Region: jsii.String("us-east-2"),
			GlobalSecondaryIndexOptions: map[string]ReplicaGlobalSecondaryIndexOptions{
				"gsi2": &ReplicaGlobalSecondaryIndexOptions{
					"contributorInsightsSpecification": &ContributorInsightsSpecification{
						"enabled": jsii.Boolean(false),
					},
				},
			},
		},
	},
})

Local Secondary Indexes ​

TableV2 can only be configured with localSecondaryIndexes when a sortKey is defined as a TableV2 property.

You can provide localSecondaryIndexes as a TableV2 property:

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  sortKey: { name: 'sk', type: dynamodb.AttributeType.NUMBER },
  localSecondaryIndexes: [
    {
      indexName: 'lsi',
      sortKey: { name: 'sk', type: dynamodb.AttributeType.NUMBER },
    },
  ],
});
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    sort_key=dynamodb.Attribute(name="sk", type=dynamodb.AttributeType.NUMBER),
    local_secondary_indexes=[dynamodb.LocalSecondaryIndexProps(
        index_name="lsi",
        sort_key=dynamodb.Attribute(name="sk", type=dynamodb.AttributeType.NUMBER)
    )
    ]
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .sortKey(Attribute.builder().name("sk").type(AttributeType.NUMBER).build())
        .localSecondaryIndexes(List.of(LocalSecondaryIndexProps.builder()
                .indexName("lsi")
                .sortKey(Attribute.builder().name("sk").type(AttributeType.NUMBER).build())
                .build()))
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    SortKey = new Attribute { Name = "sk", Type = AttributeType.NUMBER },
    LocalSecondaryIndexes = new [] { new LocalSecondaryIndexProps {
        IndexName = "lsi",
        SortKey = new Attribute { Name = "sk", Type = AttributeType.NUMBER }
    } }
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	SortKey: &Attribute{
		Name: jsii.String("sk"),
		Type: dynamodb.AttributeType_NUMBER,
	},
	LocalSecondaryIndexes: []LocalSecondaryIndexProps{
		&LocalSecondaryIndexProps{
			IndexName: jsii.String("lsi"),
			SortKey: &Attribute{
				Name: jsii.String("sk"),
				Type: dynamodb.AttributeType_NUMBER,
			},
		},
	},
})

Alternatively, you can add a localSecondaryIndex using the addLocalSecondaryIndex method:

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  sortKey: { name: 'sk', type: dynamodb.AttributeType.NUMBER },
  localSecondaryIndexes: [
    {
      indexName: 'lsi1',
      sortKey: { name: 'sk', type: dynamodb.AttributeType.NUMBER },
    },
  ],
});

table.addLocalSecondaryIndex({
  indexName: 'lsi2',
  sortKey: { name: 'sk', type: dynamodb.AttributeType.NUMBER },
});
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    sort_key=dynamodb.Attribute(name="sk", type=dynamodb.AttributeType.NUMBER),
    local_secondary_indexes=[dynamodb.LocalSecondaryIndexProps(
        index_name="lsi1",
        sort_key=dynamodb.Attribute(name="sk", type=dynamodb.AttributeType.NUMBER)
    )
    ]
)

table.add_local_secondary_index(
    index_name="lsi2",
    sort_key=dynamodb.Attribute(name="sk", type=dynamodb.AttributeType.NUMBER)
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .sortKey(Attribute.builder().name("sk").type(AttributeType.NUMBER).build())
        .localSecondaryIndexes(List.of(LocalSecondaryIndexProps.builder()
                .indexName("lsi1")
                .sortKey(Attribute.builder().name("sk").type(AttributeType.NUMBER).build())
                .build()))
        .build();

table.addLocalSecondaryIndex(LocalSecondaryIndexProps.builder()
        .indexName("lsi2")
        .sortKey(Attribute.builder().name("sk").type(AttributeType.NUMBER).build())
        .build());
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    SortKey = new Attribute { Name = "sk", Type = AttributeType.NUMBER },
    LocalSecondaryIndexes = new [] { new LocalSecondaryIndexProps {
        IndexName = "lsi1",
        SortKey = new Attribute { Name = "sk", Type = AttributeType.NUMBER }
    } }
});

table.AddLocalSecondaryIndex(new LocalSecondaryIndexProps {
    IndexName = "lsi2",
    SortKey = new Attribute { Name = "sk", Type = AttributeType.NUMBER }
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	SortKey: &Attribute{
		Name: jsii.String("sk"),
		Type: dynamodb.AttributeType_NUMBER,
	},
	LocalSecondaryIndexes: []LocalSecondaryIndexProps{
		&LocalSecondaryIndexProps{
			IndexName: jsii.String("lsi1"),
			SortKey: &Attribute{
				Name: jsii.String("sk"),
				Type: dynamodb.AttributeType_NUMBER,
			},
		},
	},
})

table.AddLocalSecondaryIndex(&LocalSecondaryIndexProps{
	IndexName: jsii.String("lsi2"),
	SortKey: &Attribute{
		Name: jsii.String("sk"),
		Type: dynamodb.AttributeType_NUMBER,
	},
})

Streams ​

Each DynamoDB table produces an independent stream based on all its writes, regardless of the origination point for those writes. DynamoDB supports two stream types:

  • DynamoDB streams - Capture item-level changes in your table, and push the changes to a DynamoDB stream. You then can access the change information through the DynamoDB Streams API.
  • Kinesis streams - Amazon Kinesis Data Streams for DynamoDB captures item-level changes in your table, and replicates the changes to a Kinesis data stream. You then can consume and manage the change information from Kinesis.

DynamoDB Streams ​

A dynamoStream can be configured as a TableV2 property. If the TableV2 instance has replica tables, then all replica tables will inherit the dynamoStream setting from the primary table. If replicas are configured, but dynamoStream is not configured, then the primary table and all replicas will be automatically configured with the NEW_AND_OLD_IMAGES stream view type.

ts
import * as cdk from 'aws-cdk-lib';
import * as kinesis from 'aws-cdk-lib/aws-kinesis';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack', { env: { region: 'us-west-2' } });

const globalTable = new dynamodb.TableV2(this, 'GlobalTable', {
  partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
  dynamoStream: dynamodb.StreamViewType.OLD_IMAGE,
  // tables in us-west-2, us-east-1, and us-east-2 all have dynamo stream type of OLD_IMAGES
  replicas: [
    { region: 'us-east-1' },
    { region: 'us-east-2' },
  ],
});
python
import aws_cdk as cdk
import aws_cdk.aws_kinesis as kinesis


app = cdk.App()
stack = cdk.Stack(app, "Stack", env=cdk.Environment(region="us-west-2"))

global_table = dynamodb.TableV2(self, "GlobalTable",
    partition_key=dynamodb.Attribute(name="id", type=dynamodb.AttributeType.STRING),
    dynamo_stream=dynamodb.StreamViewType.OLD_IMAGE,
    # tables in us-west-2, us-east-1, and us-east-2 all have dynamo stream type of OLD_IMAGES
    replicas=[dynamodb.ReplicaTableProps(region="us-east-1"), dynamodb.ReplicaTableProps(region="us-east-2")
    ]
)
java
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.kinesis.*;


App app = new App();
Stack stack = Stack.Builder.create(app, "Stack").env(Environment.builder().region("us-west-2").build()).build();

TableV2 globalTable = TableV2.Builder.create(this, "GlobalTable")
        .partitionKey(Attribute.builder().name("id").type(AttributeType.STRING).build())
        .dynamoStream(StreamViewType.OLD_IMAGE)
        // tables in us-west-2, us-east-1, and us-east-2 all have dynamo stream type of OLD_IMAGES
        .replicas(List.of(ReplicaTableProps.builder().region("us-east-1").build(), ReplicaTableProps.builder().region("us-east-2").build()))
        .build();
csharp
using Amazon.CDK;
using Amazon.CDK.AWS.Kinesis;


var app = new App();
var stack = new Stack(app, "Stack", new StackProps { Env = new Environment { Region = "us-west-2" } });

var globalTable = new TableV2(this, "GlobalTable", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "id", Type = AttributeType.STRING },
    DynamoStream = StreamViewType.OLD_IMAGE,
    // tables in us-west-2, us-east-1, and us-east-2 all have dynamo stream type of OLD_IMAGES
    Replicas = new [] { new ReplicaTableProps { Region = "us-east-1" }, new ReplicaTableProps { Region = "us-east-2" } }
});
go
import "github.com/aws/aws-cdk-go/awscdk"
import kinesis "github.com/aws/aws-cdk-go/awscdk"


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})

globalTable := dynamodb.NewTableV2(this, jsii.String("GlobalTable"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("id"),
		Type: dynamodb.AttributeType_STRING,
	},
	DynamoStream: dynamodb.StreamViewType_OLD_IMAGE,
	// tables in us-west-2, us-east-1, and us-east-2 all have dynamo stream type of OLD_IMAGES
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-east-1"),
		},
		&ReplicaTableProps{
			Region: jsii.String("us-east-2"),
		},
	},
})

Further reading: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html

Kinesis Streams ​

A kinesisStream can be configured as a TableV2 property. Replica tables will not inherit the kinesisStream configured for the primary table and should added on a per-replica basis.

ts
import * as cdk from 'aws-cdk-lib';
import * as kinesis from 'aws-cdk-lib/aws-kinesis';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack', { env: { region: 'us-west-2' } });

const stream1 = new kinesis.Stream(stack, 'Stream1');
const stream2 = kinesis.Stream.fromStreamArn(stack, 'Stream2', 'arn:aws:kinesis:us-east-2:123456789012:stream/my-stream');

const globalTable = new dynamodb.TableV2(this, 'GlobalTable', {
  partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
  kinesisStream: stream1, // for table in us-west-2
  replicas: [
    { region: 'us-east-1' }, // no kinesis data stream will be set for this replica
    {
      region: 'us-east-2',
      kinesisStream: stream2, // for table in us-east-2
    },
  ],
});
python
import aws_cdk as cdk
import aws_cdk.aws_kinesis as kinesis


app = cdk.App()
stack = cdk.Stack(app, "Stack", env=cdk.Environment(region="us-west-2"))

stream1 = kinesis.Stream(stack, "Stream1")
stream2 = kinesis.Stream.from_stream_arn(stack, "Stream2", "arn:aws:kinesis:us-east-2:123456789012:stream/my-stream")

global_table = dynamodb.TableV2(self, "GlobalTable",
    partition_key=dynamodb.Attribute(name="id", type=dynamodb.AttributeType.STRING),
    kinesis_stream=stream1,  # for table in us-west-2
    replicas=[dynamodb.ReplicaTableProps(region="us-east-1"), dynamodb.ReplicaTableProps(
        region="us-east-2",
        kinesis_stream=stream2
    )
    ]
)
java
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.kinesis.*;


App app = new App();
Stack stack = Stack.Builder.create(app, "Stack").env(Environment.builder().region("us-west-2").build()).build();

Stream stream1 = new Stream(stack, "Stream1");
IStream stream2 = Stream.fromStreamArn(stack, "Stream2", "arn:aws:kinesis:us-east-2:123456789012:stream/my-stream");

TableV2 globalTable = TableV2.Builder.create(this, "GlobalTable")
        .partitionKey(Attribute.builder().name("id").type(AttributeType.STRING).build())
        .kinesisStream(stream1) // for table in us-west-2
        .replicas(List.of(ReplicaTableProps.builder().region("us-east-1").build(), ReplicaTableProps.builder()
                .region("us-east-2")
                .kinesisStream(stream2)
                .build()))
        .build();
csharp
using Amazon.CDK;
using Amazon.CDK.AWS.Kinesis;


var app = new App();
var stack = new Stack(app, "Stack", new StackProps { Env = new Environment { Region = "us-west-2" } });

var stream1 = new Stream(stack, "Stream1");
var stream2 = Stream.FromStreamArn(stack, "Stream2", "arn:aws:kinesis:us-east-2:123456789012:stream/my-stream");

var globalTable = new TableV2(this, "GlobalTable", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "id", Type = AttributeType.STRING },
    KinesisStream = stream1,  // for table in us-west-2
    Replicas = new [] { new ReplicaTableProps { Region = "us-east-1" }, new ReplicaTableProps {
        Region = "us-east-2",
        KinesisStream = stream2
    } }
});
go
import "github.com/aws/aws-cdk-go/awscdk"
import "github.com/aws/aws-cdk-go/awscdk"


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})

stream1 := kinesis.NewStream(stack, jsii.String("Stream1"))
stream2 := kinesis.Stream_FromStreamArn(stack, jsii.String("Stream2"), jsii.String("arn:aws:kinesis:us-east-2:123456789012:stream/my-stream"))

globalTable := dynamodb.NewTableV2(this, jsii.String("GlobalTable"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("id"),
		Type: dynamodb.AttributeType_STRING,
	},
	KinesisStream: stream1,
	 // for table in us-west-2
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-east-1"),
		},
		&ReplicaTableProps{
			Region: jsii.String("us-east-2"),
			KinesisStream: stream2,
		},
	},
})

Further reading: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/kds.html

Keys ​

When an instance of the TableV2 construct is defined, you must define its schema using the partitionKey (required) and sortKey (optional) properties.

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  sortKey: { name: 'sk', type: dynamodb.AttributeType.NUMBER },
});
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    sort_key=dynamodb.Attribute(name="sk", type=dynamodb.AttributeType.NUMBER)
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .sortKey(Attribute.builder().name("sk").type(AttributeType.NUMBER).build())
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    SortKey = new Attribute { Name = "sk", Type = AttributeType.NUMBER }
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	SortKey: &Attribute{
		Name: jsii.String("sk"),
		Type: dynamodb.AttributeType_NUMBER,
	},
})

Contributor Insights ​

Enabling contributorInsightSpecification for TableV2 will provide information about the most accessed and throttled or throttled only items in a table or globalSecondaryIndex. DynamoDB delivers this information to you via CloudWatch Contributor Insights rules, reports, and graphs of report data.

By default, Contributor Insights for DynamoDB monitors all requests, including both the most accessed and most throttled items. To limit the scope to only the most accessed or only the most throttled items, use the optional mode parameter.

  • To monitor all traffic on a table or index, set mode to ContributorInsightsMode.ACCESSED_AND_THROTTLED_KEYS.
  • To monitor only throttled traffic on a table or index, set mode to ContributorInsightsMode.THROTTLED_KEYS.
ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  contributorInsightsSpecification: {
    enabled: true,
    mode: dynamodb.ContributorInsightsMode.ACCESSED_AND_THROTTLED_KEYS,
  },
});
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    contributor_insights_specification=dynamodb.ContributorInsightsSpecification(
        enabled=True,
        mode=dynamodb.ContributorInsightsMode.ACCESSED_AND_THROTTLED_KEYS
    )
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .contributorInsightsSpecification(ContributorInsightsSpecification.builder()
                .enabled(true)
                .mode(ContributorInsightsMode.ACCESSED_AND_THROTTLED_KEYS)
                .build())
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    ContributorInsightsSpecification = new ContributorInsightsSpecification {
        Enabled = true,
        Mode = ContributorInsightsMode.ACCESSED_AND_THROTTLED_KEYS
    }
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	ContributorInsightsSpecification: &ContributorInsightsSpecification{
		Enabled: jsii.Boolean(true),
		Mode: dynamodb.ContributorInsightsMode_ACCESSED_AND_THROTTLED_KEYS,
	},
})

When you use Table, you can enable contributor insights for a table or specific global secondary index by setting contributorInsightsSpecification parameter enabled to true.

ts
const table = new dynamodb.Table(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  contributorInsightsSpecification: { // for a table
    enabled: true,
    mode: dynamodb.ContributorInsightsMode.THROTTLED_KEYS, // only emit throttling events
  },
});

table.addGlobalSecondaryIndex({
  contributorInsightsSpecification: { // for a specific global secondary index
    enabled: true,
  },
  indexName: 'gsi',
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
});
python
table = dynamodb.Table(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    contributor_insights_specification=dynamodb.ContributorInsightsSpecification( # for a table
        enabled=True,
        mode=dynamodb.ContributorInsightsMode.THROTTLED_KEYS)
)

table.add_global_secondary_index(
    contributor_insights_specification=dynamodb.ContributorInsightsSpecification( # for a specific global secondary index
        enabled=True),
    index_name="gsi",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING)
)
java
Table table = Table.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .contributorInsightsSpecification(ContributorInsightsSpecification.builder() // for a table
                .enabled(true)
                .mode(ContributorInsightsMode.THROTTLED_KEYS).build())
        .build();

table.addGlobalSecondaryIndex(GlobalSecondaryIndexProps.builder()
        .contributorInsightsSpecification(ContributorInsightsSpecification.builder() // for a specific global secondary index
                .enabled(true).build())
        .indexName("gsi")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .build());
csharp
var table = new Table(this, "Table", new TableProps {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    ContributorInsightsSpecification = new ContributorInsightsSpecification {  // for a table
        Enabled = true,
        Mode = ContributorInsightsMode.THROTTLED_KEYS }
});

table.AddGlobalSecondaryIndex(new GlobalSecondaryIndexProps {
    ContributorInsightsSpecification = new ContributorInsightsSpecification {  // for a specific global secondary index
        Enabled = true },
    IndexName = "gsi",
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING }
});
go
table := dynamodb.NewTable(this, jsii.String("Table"), &TableProps{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	ContributorInsightsSpecification: &ContributorInsightsSpecification{
		 // for a table
		Enabled: jsii.Boolean(true),
		Mode: dynamodb.ContributorInsightsMode_THROTTLED_KEYS,
	},
})

table.AddGlobalSecondaryIndex(&GlobalSecondaryIndexProps{
	ContributorInsightsSpecification: &ContributorInsightsSpecification{
		 // for a specific global secondary index
		Enabled: jsii.Boolean(true),
	},
	IndexName: jsii.String("gsi"),
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
})

Further reading: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/contributorinsights_HowItWorks.html

Deletion Protection ​

deletionProtection determines if your DynamoDB table is protected from deletion and is configurable as a TableV2 property. When enabled, the table cannot be deleted by any user or process.

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  deletionProtection: true,
});
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    deletion_protection=True
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .deletionProtection(true)
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    DeletionProtection = true
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	DeletionProtection: jsii.Boolean(true),
})

You can also specify the removalPolicy as a property of the TableV2 construct. This property allows you to control what happens to tables provisioned using TableV2 during stack deletion. By default, the removalPolicy is RETAIN which will cause all tables provisioned using TableV2 to be retained in the account, but orphaned from the stack they were created in. You can also set the removalPolicy to DESTROY which will delete all tables created using TableV2 during stack deletion:

ts
import * as cdk from 'aws-cdk-lib';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack', { env: { region: 'us-west-2' } });

const globalTable = new dynamodb.TableV2(stack, 'GlobalTable', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  // applies to all replicas, i.e., us-west-2, us-east-1, us-east-2
  removalPolicy: cdk.RemovalPolicy.DESTROY,
  replicas: [
    { region: 'us-east-1' },
    { region: 'us-east-2' },
  ],
});
python
import aws_cdk as cdk


app = cdk.App()
stack = cdk.Stack(app, "Stack", env=cdk.Environment(region="us-west-2"))

global_table = dynamodb.TableV2(stack, "GlobalTable",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    # applies to all replicas, i.e., us-west-2, us-east-1, us-east-2
    removal_policy=cdk.RemovalPolicy.DESTROY,
    replicas=[dynamodb.ReplicaTableProps(region="us-east-1"), dynamodb.ReplicaTableProps(region="us-east-2")
    ]
)
java
import software.amazon.awscdk.*;


App app = new App();
Stack stack = Stack.Builder.create(app, "Stack").env(Environment.builder().region("us-west-2").build()).build();

TableV2 globalTable = TableV2.Builder.create(stack, "GlobalTable")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        // applies to all replicas, i.e., us-west-2, us-east-1, us-east-2
        .removalPolicy(RemovalPolicy.DESTROY)
        .replicas(List.of(ReplicaTableProps.builder().region("us-east-1").build(), ReplicaTableProps.builder().region("us-east-2").build()))
        .build();
csharp
using Amazon.CDK;


var app = new App();
var stack = new Stack(app, "Stack", new StackProps { Env = new Environment { Region = "us-west-2" } });

var globalTable = new TableV2(stack, "GlobalTable", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    // applies to all replicas, i.e., us-west-2, us-east-1, us-east-2
    RemovalPolicy = RemovalPolicy.DESTROY,
    Replicas = new [] { new ReplicaTableProps { Region = "us-east-1" }, new ReplicaTableProps { Region = "us-east-2" } }
});
go
import "github.com/aws/aws-cdk-go/awscdk"


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})

globalTable := dynamodb.NewTableV2(stack, jsii.String("GlobalTable"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	// applies to all replicas, i.e., us-west-2, us-east-1, us-east-2
	RemovalPolicy: cdk.RemovalPolicy_DESTROY,
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-east-1"),
		},
		&ReplicaTableProps{
			Region: jsii.String("us-east-2"),
		},
	},
})

deletionProtection is configurable on a per-replica basis. If the removalPolicy is set to DESTROY, but some replicas have deletionProtection enabled, then only the replicas without deletionProtection will be deleted during stack deletion:

ts
import * as cdk from 'aws-cdk-lib';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack', { env: { region: 'us-west-2' } });

const globalTable = new dynamodb.TableV2(stack, 'GlobalTable', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  removalPolicy: cdk.RemovalPolicy.DESTROY,
  deletionProtection: true,
  // only the replica in us-east-1 will be deleted during stack deletion
  replicas: [
    {
      region: 'us-east-1',
      deletionProtection: false,
    },
    {
      region: 'us-east-2',
      deletionProtection: true,
    },
  ],
});
python
import aws_cdk as cdk


app = cdk.App()
stack = cdk.Stack(app, "Stack", env=cdk.Environment(region="us-west-2"))

global_table = dynamodb.TableV2(stack, "GlobalTable",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    removal_policy=cdk.RemovalPolicy.DESTROY,
    deletion_protection=True,
    # only the replica in us-east-1 will be deleted during stack deletion
    replicas=[dynamodb.ReplicaTableProps(
        region="us-east-1",
        deletion_protection=False
    ), dynamodb.ReplicaTableProps(
        region="us-east-2",
        deletion_protection=True
    )
    ]
)
java
import software.amazon.awscdk.*;


App app = new App();
Stack stack = Stack.Builder.create(app, "Stack").env(Environment.builder().region("us-west-2").build()).build();

TableV2 globalTable = TableV2.Builder.create(stack, "GlobalTable")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .removalPolicy(RemovalPolicy.DESTROY)
        .deletionProtection(true)
        // only the replica in us-east-1 will be deleted during stack deletion
        .replicas(List.of(ReplicaTableProps.builder()
                .region("us-east-1")
                .deletionProtection(false)
                .build(), ReplicaTableProps.builder()
                .region("us-east-2")
                .deletionProtection(true)
                .build()))
        .build();
csharp
using Amazon.CDK;


var app = new App();
var stack = new Stack(app, "Stack", new StackProps { Env = new Environment { Region = "us-west-2" } });

var globalTable = new TableV2(stack, "GlobalTable", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    RemovalPolicy = RemovalPolicy.DESTROY,
    DeletionProtection = true,
    // only the replica in us-east-1 will be deleted during stack deletion
    Replicas = new [] { new ReplicaTableProps {
        Region = "us-east-1",
        DeletionProtection = false
    }, new ReplicaTableProps {
        Region = "us-east-2",
        DeletionProtection = true
    } }
});
go
import "github.com/aws/aws-cdk-go/awscdk"


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})

globalTable := dynamodb.NewTableV2(stack, jsii.String("GlobalTable"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	RemovalPolicy: cdk.RemovalPolicy_DESTROY,
	DeletionProtection: jsii.Boolean(true),
	// only the replica in us-east-1 will be deleted during stack deletion
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-east-1"),
			DeletionProtection: jsii.Boolean(false),
		},
		&ReplicaTableProps{
			Region: jsii.String("us-east-2"),
			DeletionProtection: jsii.Boolean(true),
		},
	},
})

Point-in-Time Recovery ​

pointInTimeRecoverySpecifcation provides automatic backups of your DynamoDB table data which helps protect your tables from accidental write or delete operations.

You can also choose to set recoveryPeriodInDays to a value between 1 and 35 which dictates how many days of recoverable data is stored. If no value is provided, the recovery period defaults to 35 days.

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  pointInTimeRecoverySpecification: {
    pointInTimeRecoveryEnabled: true,
    recoveryPeriodInDays: 4,
  },
});
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    point_in_time_recovery_specification=dynamodb.PointInTimeRecoverySpecification(
        point_in_time_recovery_enabled=True,
        recovery_period_in_days=4
    )
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .pointInTimeRecoverySpecification(PointInTimeRecoverySpecification.builder()
                .pointInTimeRecoveryEnabled(true)
                .recoveryPeriodInDays(4)
                .build())
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    PointInTimeRecoverySpecification = new PointInTimeRecoverySpecification {
        PointInTimeRecoveryEnabled = true,
        RecoveryPeriodInDays = 4
    }
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	PointInTimeRecoverySpecification: &PointInTimeRecoverySpecification{
		PointInTimeRecoveryEnabled: jsii.Boolean(true),
		RecoveryPeriodInDays: jsii.Number(4),
	},
})

Table Class ​

You can configure a TableV2 instance with table classes:

  • STANDARD - the default mode, and is recommended for the vast majority of workloads.
  • STANDARD_INFREQUENT_ACCESS - optimized for tables where storage is the dominant cost.
ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  tableClass: dynamodb.TableClass.STANDARD_INFREQUENT_ACCESS,
});
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    table_class=dynamodb.TableClass.STANDARD_INFREQUENT_ACCESS
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .tableClass(TableClass.STANDARD_INFREQUENT_ACCESS)
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    TableClass = TableClass.STANDARD_INFREQUENT_ACCESS
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	TableClass: dynamodb.TableClass_STANDARD_INFREQUENT_ACCESS,
})

Further reading: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.TableClasses.html

Tags ​

You can add tags to a TableV2 in several ways. By adding the tags to the construct itself it will apply the tags to the primary table.

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  tags: [{key: 'primaryTableTagKey', value: 'primaryTableTagValue'}],
});
python
from aws_cdk import CfnTag
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    tags=[CfnTag(key="primaryTableTagKey", value="primaryTableTagValue")]
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .tags(List.of(CfnTag.builder().key("primaryTableTagKey").value("primaryTableTagValue").build()))
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    Tags = new [] { new CfnTag { Key = "primaryTableTagKey", Value = "primaryTableTagValue" } }
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	Tags: []CfnTag{
		&CfnTag{
			Key: jsii.String("primaryTableTagKey"),
			Value: jsii.String("primaryTableTagValue"),
		},
	},
})

You can also add tags to replica tables by specifying them within the replica table properties.

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  replicas: [
    {
      region: 'us-west-1',
      tags: [{key: 'replicaTableTagKey', value: 'replicaTableTagValue'}]
    }
  ]
});
python
from aws_cdk import CfnTag
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    replicas=[dynamodb.ReplicaTableProps(
        region="us-west-1",
        tags=[CfnTag(key="replicaTableTagKey", value="replicaTableTagValue")]
    )
    ]
)
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .replicas(List.of(ReplicaTableProps.builder()
                .region("us-west-1")
                .tags(List.of(CfnTag.builder().key("replicaTableTagKey").value("replicaTableTagValue").build()))
                .build()))
        .build();
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    Replicas = new [] { new ReplicaTableProps {
        Region = "us-west-1",
        Tags = new [] { new CfnTag { Key = "replicaTableTagKey", Value = "replicaTableTagValue" } }
    } }
});
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-west-1"),
			Tags: []CfnTag{
				&CfnTag{
					Key: jsii.String("replicaTableTagKey"),
					Value: jsii.String("replicaTableTagValue"),
				},
			},
		},
	},
})

Referencing Existing Global Tables ​

To reference an existing DynamoDB table in your CDK application, use the TableV2.fromTableName, TableV2.fromTableArn, or TableV2.fromTableAttributes factory methods:

ts
declare const user: iam.User;

const table = dynamodb.TableV2.fromTableArn(this, 'ImportedTable', 'arn:aws:dynamodb:us-east-1:123456789012:table/my-table');
// now you can call methods on the referenced table
table.grantReadWriteData(user);
python
# user: iam.User


table = dynamodb.TableV2.from_table_arn(self, "ImportedTable", "arn:aws:dynamodb:us-east-1:123456789012:table/my-table")
# now you can call methods on the referenced table
table.grant_read_write_data(user)
java
User user;


ITableV2 table = TableV2.fromTableArn(this, "ImportedTable", "arn:aws:dynamodb:us-east-1:123456789012:table/my-table");
// now you can call methods on the referenced table
table.grantReadWriteData(user);
csharp
User user;


var table = TableV2.FromTableArn(this, "ImportedTable", "arn:aws:dynamodb:us-east-1:123456789012:table/my-table");
// now you can call methods on the referenced table
table.GrantReadWriteData(user);
go
var user User


table := dynamodb.TableV2_FromTableArn(this, jsii.String("ImportedTable"), jsii.String("arn:aws:dynamodb:us-east-1:123456789012:table/my-table"))
// now you can call methods on the referenced table
table.GrantReadWriteData(user)

If you intend to use the tableStreamArn (including indirectly, for example by creating an aws-cdk-lib/aws-lambda-event-sources.DynamoEventSource on the referenced table), you must use the TableV2.fromTableAttributes method and the tableStreamArn property must be populated.

To grant permissions to indexes for a referenced table you can either set grantIndexPermissions to true, or you can provide the indexes via the globalIndexes or localIndexes properties. This will enable grant* methods to also grant permissions to all table indexes.

Resource Policy ​

Using resourcePolicy you can add a resource policy to a table in the form of a PolicyDocument:

    // resource policy document
    const policy = new iam.PolicyDocument({
      statements: [
        new iam.PolicyStatement({
          actions: ['dynamodb:GetItem'],
          principals: [new iam.AccountRootPrincipal()],
          resources: ['*'],
        }),
      ],
    });

    // table with resource policy
    new dynamodb.TableV2(this, 'TableTestV2-1', {
      partitionKey: {
        name: 'id',
        type: dynamodb.AttributeType.STRING,
      },
      removalPolicy: RemovalPolicy.DESTROY,
      resourcePolicy: policy,
    });

Adding Resource Policy Statements Dynamically ​

You can also add resource policy statements to a table after it's created using the addToResourcePolicy method. Following the same pattern as KMS, resource policies use wildcard resources to avoid circular dependencies:

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
});

// Standard resource policy (recommended approach)
table.addToResourcePolicy(new iam.PolicyStatement({
  actions: ['dynamodb:GetItem', 'dynamodb:PutItem', 'dynamodb:Query'],
  principals: [new iam.AccountRootPrincipal()],
  resources: ['*'], // Wildcard avoids circular dependency - same pattern as KMS
}));

// Allow specific service access
table.addToResourcePolicy(new iam.PolicyStatement({
  actions: ['dynamodb:Query'],
  principals: [new iam.ServicePrincipal('lambda.amazonaws.com')],
  resources: ['*'],
}));
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING)
)

# Standard resource policy (recommended approach)
table.add_to_resource_policy(iam.PolicyStatement(
    actions=["dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query"],
    principals=[iam.AccountRootPrincipal()],
    resources=["*"]
))

# Allow specific service access
table.add_to_resource_policy(iam.PolicyStatement(
    actions=["dynamodb:Query"],
    principals=[iam.ServicePrincipal("lambda.amazonaws.com")],
    resources=["*"]
))
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .build();

// Standard resource policy (recommended approach)
table.addToResourcePolicy(PolicyStatement.Builder.create()
        .actions(List.of("dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query"))
        .principals(List.of(new AccountRootPrincipal()))
        .resources(List.of("*"))
        .build());

// Allow specific service access
table.addToResourcePolicy(PolicyStatement.Builder.create()
        .actions(List.of("dynamodb:Query"))
        .principals(List.of(new ServicePrincipal("lambda.amazonaws.com")))
        .resources(List.of("*"))
        .build());
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING }
});

// Standard resource policy (recommended approach)
table.AddToResourcePolicy(new PolicyStatement(new PolicyStatementProps {
    Actions = new [] { "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query" },
    Principals = new [] { new AccountRootPrincipal() },
    Resources = new [] { "*" }
}));

// Allow specific service access
table.AddToResourcePolicy(new PolicyStatement(new PolicyStatementProps {
    Actions = new [] { "dynamodb:Query" },
    Principals = new [] { new ServicePrincipal("lambda.amazonaws.com") },
    Resources = new [] { "*" }
}));
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
})

// Standard resource policy (recommended approach)
table.AddToResourcePolicy(iam.NewPolicyStatement(&PolicyStatementProps{
	Actions: []*string{
		jsii.String("dynamodb:GetItem"),
		jsii.String("dynamodb:PutItem"),
		jsii.String("dynamodb:Query"),
	},
	Principals: []IPrincipal{
		iam.NewAccountRootPrincipal(),
	},
	Resources: []*string{
		jsii.String("*"),
	},
}))

// Allow specific service access
table.AddToResourcePolicy(iam.NewPolicyStatement(&PolicyStatementProps{
	Actions: []*string{
		jsii.String("dynamodb:Query"),
	},
	Principals: []IPrincipal{
		iam.NewServicePrincipal(jsii.String("lambda.amazonaws.com")),
	},
	Resources: []*string{
		jsii.String("*"),
	},
}))

Scoped Resource Policies (Advanced) ​

For scoped resource policies that reference specific table ARNs, you must specify an explicit table name:

ts
import { Fn } from 'aws-cdk-lib';

// Table with explicit name enables scoped resource policies
const table = new dynamodb.TableV2(this, 'Table', {
  tableName: 'my-explicit-table-name', // Required for scoped resources
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
});

// Now you can use scoped resources
table.addToResourcePolicy(new iam.PolicyStatement({
  actions: ['dynamodb:GetItem'],
  principals: [new iam.AccountRootPrincipal()],
  resources: [
    Fn.sub('arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/my-explicit-table-name'),
    Fn.sub('arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/my-explicit-table-name/index/*'),
  ],
}));
python
from aws_cdk import Fn


# Table with explicit name enables scoped resource policies
table = dynamodb.TableV2(self, "Table",
    table_name="my-explicit-table-name",  # Required for scoped resources
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING)
)

# Now you can use scoped resources
table.add_to_resource_policy(iam.PolicyStatement(
    actions=["dynamodb:GetItem"],
    principals=[iam.AccountRootPrincipal()],
    resources=[
        Fn.sub("arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/my-explicit-table-name"),
        Fn.sub("arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/my-explicit-table-name/index/*")
    ]
))
java
import software.amazon.awscdk.Fn;


// Table with explicit name enables scoped resource policies
TableV2 table = TableV2.Builder.create(this, "Table")
        .tableName("my-explicit-table-name") // Required for scoped resources
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .build();

// Now you can use scoped resources
table.addToResourcePolicy(PolicyStatement.Builder.create()
        .actions(List.of("dynamodb:GetItem"))
        .principals(List.of(new AccountRootPrincipal()))
        .resources(List.of(Fn.sub("arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/my-explicit-table-name"), Fn.sub("arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/my-explicit-table-name/index/*")))
        .build());
csharp
using Amazon.CDK;


// Table with explicit name enables scoped resource policies
var table = new TableV2(this, "Table", new TablePropsV2 {
    TableName = "my-explicit-table-name",  // Required for scoped resources
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING }
});

// Now you can use scoped resources
table.AddToResourcePolicy(new PolicyStatement(new PolicyStatementProps {
    Actions = new [] { "dynamodb:GetItem" },
    Principals = new [] { new AccountRootPrincipal() },
    Resources = new [] { Fn.Sub("arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/my-explicit-table-name"), Fn.Sub("arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/my-explicit-table-name/index/*") }
}));
go
import "github.com/aws/aws-cdk-go/awscdk"


// Table with explicit name enables scoped resource policies
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	TableName: jsii.String("my-explicit-table-name"),
	 // Required for scoped resources
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
})

// Now you can use scoped resources
table.AddToResourcePolicy(iam.NewPolicyStatement(&PolicyStatementProps{
	Actions: []*string{
		jsii.String("dynamodb:GetItem"),
	},
	Principals: []IPrincipal{
		iam.NewAccountRootPrincipal(),
	},
	Resources: []*string{
		awscdk.Fn_Sub(jsii.String("arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/my-explicit-table-name")),
		awscdk.Fn_*Sub(jsii.String("arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/my-explicit-table-name/index/*")),
	},
}))

Important Limitations:

  • Auto-generated table names: Must use resources: ['*'] to avoid circular dependencies
  • Explicit table names: Enable scoped resources but lose CDK's automatic naming benefits
  • CloudFormation constraint: Resource policies cannot reference the resource they're attached to during creation

TableV2 doesn’t support creating a replica and adding a resource-based policy to that replica in the same stack update in Regions other than the Region where you deploy the stack update. To incorporate a resource-based policy into a replica, you'll need to initially deploy the replica without the policy, followed by a subsequent update to include the desired policy.

Grant Methods and Resource Policies ​

Grant methods like grantReadData(), grantWriteData(), and grantReadWriteData() automatically add permissions to resource policies when used with same-account principals (like AccountRootPrincipal). This happens transparently:

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
});

// Automatically adds to table's resource policy (same account)
table.grantReadData(new iam.AccountRootPrincipal());

// Adds to IAM user's policy (not resource policy)
declare const user: iam.User;
table.grantReadData(user);
python
# Adds to IAM user's policy (not resource policy)
# user: iam.User
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING)
)

# Automatically adds to table's resource policy (same account)
table.grant_read_data(iam.AccountRootPrincipal())
table.grant_read_data(user)
java
// Adds to IAM user's policy (not resource policy)
User user;
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .build();

// Automatically adds to table's resource policy (same account)
table.grantReadData(new AccountRootPrincipal());
table.grantReadData(user);
csharp
// Adds to IAM user's policy (not resource policy)
User user;
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING }
});

// Automatically adds to table's resource policy (same account)
table.GrantReadData(new AccountRootPrincipal());
table.GrantReadData(user);
go
// Adds to IAM user's policy (not resource policy)
var user User
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
})

// Automatically adds to table's resource policy (same account)
table.GrantReadData(iam.NewAccountRootPrincipal())
table.GrantReadData(user)

How it works:

  • Same-account principals (AccountRootPrincipal, AccountPrincipal): Grant adds statement to table's resource policy
  • IAM identities (User, Role, Group): Grant adds statement to the identity's IAM policy
  • Resource policy statements: Automatically use wildcard resources (*) to avoid circular dependencies

This behavior follows the same pattern as other AWS services like KMS and S3, where grants intelligently choose between resource policies and identity policies based on the principal type.

To avoid wildcards in resource policies: If you need scoped resource ARNs instead of wildcards, use addToResourcePolicy() directly with an explicit table name instead of grant methods. See the "Scoped Resource Policies (Advanced)" section above for details.

Stream Resource Policy ​

You can attach a resource policy to a DynamoDB stream using streamResourcePolicy. This applies per-replica, so you can set different policies for the primary table and each replica:

ts
const streamPolicy = new iam.PolicyDocument({
  statements: [
    new iam.PolicyStatement({
      actions: ['dynamodb:DescribeStream', 'dynamodb:GetRecords', 'dynamodb:GetShardIterator'],
      principals: [new iam.AccountRootPrincipal()],
      resources: ['*'],
    }),
  ],
});

new dynamodb.TableV2(this, 'GlobalTable', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  dynamoStream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES,
  streamResourcePolicy: streamPolicy,
  replicas: [
    {
      region: 'us-west-2',
      streamResourcePolicy: streamPolicy,
    },
  ],
});
python
stream_policy = iam.PolicyDocument(
    statements=[
        iam.PolicyStatement(
            actions=["dynamodb:DescribeStream", "dynamodb:GetRecords", "dynamodb:GetShardIterator"],
            principals=[iam.AccountRootPrincipal()],
            resources=["*"]
        )
    ]
)

dynamodb.TableV2(self, "GlobalTable",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    dynamo_stream=dynamodb.StreamViewType.NEW_AND_OLD_IMAGES,
    stream_resource_policy=stream_policy,
    replicas=[dynamodb.ReplicaTableProps(
        region="us-west-2",
        stream_resource_policy=stream_policy
    )
    ]
)
java
PolicyDocument streamPolicy = PolicyDocument.Builder.create()
        .statements(List.of(
            PolicyStatement.Builder.create()
                    .actions(List.of("dynamodb:DescribeStream", "dynamodb:GetRecords", "dynamodb:GetShardIterator"))
                    .principals(List.of(new AccountRootPrincipal()))
                    .resources(List.of("*"))
                    .build()))
        .build();

TableV2.Builder.create(this, "GlobalTable")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .dynamoStream(StreamViewType.NEW_AND_OLD_IMAGES)
        .streamResourcePolicy(streamPolicy)
        .replicas(List.of(ReplicaTableProps.builder()
                .region("us-west-2")
                .streamResourcePolicy(streamPolicy)
                .build()))
        .build();
csharp
var streamPolicy = new PolicyDocument(new PolicyDocumentProps {
    Statements = new [] {
        new PolicyStatement(new PolicyStatementProps {
            Actions = new [] { "dynamodb:DescribeStream", "dynamodb:GetRecords", "dynamodb:GetShardIterator" },
            Principals = new [] { new AccountRootPrincipal() },
            Resources = new [] { "*" }
        }) }
});

new TableV2(this, "GlobalTable", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    DynamoStream = StreamViewType.NEW_AND_OLD_IMAGES,
    StreamResourcePolicy = streamPolicy,
    Replicas = new [] { new ReplicaTableProps {
        Region = "us-west-2",
        StreamResourcePolicy = streamPolicy
    } }
});
go
streamPolicy := iam.NewPolicyDocument(&PolicyDocumentProps{
	Statements: []PolicyStatement{
		iam.NewPolicyStatement(&PolicyStatementProps{
			Actions: []*string{
				jsii.String("dynamodb:DescribeStream"),
				jsii.String("dynamodb:GetRecords"),
				jsii.String("dynamodb:GetShardIterator"),
			},
			Principals: []IPrincipal{
				iam.NewAccountRootPrincipal(),
			},
			Resources: []*string{
				jsii.String("*"),
			},
		}),
	},
})

dynamodb.NewTableV2(this, jsii.String("GlobalTable"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	DynamoStream: dynamodb.StreamViewType_NEW_AND_OLD_IMAGES,
	StreamResourcePolicy: streamPolicy,
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-west-2"),
			StreamResourcePolicy: streamPolicy,
		},
	},
})

You can also add stream resource policy statements dynamically using addToStreamResourcePolicy:

ts
const table = new dynamodb.TableV2(this, 'Table', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  dynamoStream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES,
});

table.addToStreamResourcePolicy(new iam.PolicyStatement({
  actions: ['dynamodb:DescribeStream', 'dynamodb:GetRecords', 'dynamodb:GetShardIterator'],
  principals: [new iam.AccountRootPrincipal()],
  resources: ['*'],
}));
python
table = dynamodb.TableV2(self, "Table",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    dynamo_stream=dynamodb.StreamViewType.NEW_AND_OLD_IMAGES
)

table.add_to_stream_resource_policy(iam.PolicyStatement(
    actions=["dynamodb:DescribeStream", "dynamodb:GetRecords", "dynamodb:GetShardIterator"],
    principals=[iam.AccountRootPrincipal()],
    resources=["*"]
))
java
TableV2 table = TableV2.Builder.create(this, "Table")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .dynamoStream(StreamViewType.NEW_AND_OLD_IMAGES)
        .build();

table.addToStreamResourcePolicy(PolicyStatement.Builder.create()
        .actions(List.of("dynamodb:DescribeStream", "dynamodb:GetRecords", "dynamodb:GetShardIterator"))
        .principals(List.of(new AccountRootPrincipal()))
        .resources(List.of("*"))
        .build());
csharp
var table = new TableV2(this, "Table", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    DynamoStream = StreamViewType.NEW_AND_OLD_IMAGES
});

table.AddToStreamResourcePolicy(new PolicyStatement(new PolicyStatementProps {
    Actions = new [] { "dynamodb:DescribeStream", "dynamodb:GetRecords", "dynamodb:GetShardIterator" },
    Principals = new [] { new AccountRootPrincipal() },
    Resources = new [] { "*" }
}));
go
table := dynamodb.NewTableV2(this, jsii.String("Table"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	DynamoStream: dynamodb.StreamViewType_NEW_AND_OLD_IMAGES,
})

table.AddToStreamResourcePolicy(iam.NewPolicyStatement(&PolicyStatementProps{
	Actions: []*string{
		jsii.String("dynamodb:DescribeStream"),
		jsii.String("dynamodb:GetRecords"),
		jsii.String("dynamodb:GetShardIterator"),
	},
	Principals: []IPrincipal{
		iam.NewAccountRootPrincipal(),
	},
	Resources: []*string{
		jsii.String("*"),
	},
}))

Note: addToStreamResourcePolicy applies to the primary table's stream only. To set a stream resource policy on a replica, pass streamResourcePolicy in the replica props.

Grants ​

Using any of the grant* methods on an instance of the TableV2 construct will only apply to the primary table, its indexes, and any associated encryptionKey. As an example, grantReadData used below will only apply the table in us-west-2:

ts
import * as cdk from 'aws-cdk-lib';
import * as kms from 'aws-cdk-lib/aws-kms';

declare const user: iam.User;

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack', { env: { region: 'us-west-2' } });

const tableKey = new kms.Key(stack, 'Key');
const replicaKeyArns = {
  'us-east-1': 'arn:aws:kms:us-east-1:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6',
  'us-east-2': 'arn:aws:kms:us-east-2:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6',
};

const globalTable = new dynamodb.TableV2(stack, 'GlobalTable', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  encryption: dynamodb.TableEncryptionV2.customerManagedKey(tableKey, replicaKeyArns),
  replicas: [
    { region: 'us-east-1' },
    { region: 'us-east-2' },
  ],
});

// grantReadData only applies to the table in us-west-2 and the tableKey
globalTable.grantReadData(user);
python
import aws_cdk as cdk
import aws_cdk.aws_kms as kms

# user: iam.User


app = cdk.App()
stack = cdk.Stack(app, "Stack", env=cdk.Environment(region="us-west-2"))

table_key = kms.Key(stack, "Key")
replica_key_arns = {
    "us-east-1": "arn:aws:kms:us-east-1:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6",
    "us-east-2": "arn:aws:kms:us-east-2:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6"
}

global_table = dynamodb.TableV2(stack, "GlobalTable",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    encryption=dynamodb.TableEncryptionV2.customer_managed_key(table_key, replica_key_arns),
    replicas=[dynamodb.ReplicaTableProps(region="us-east-1"), dynamodb.ReplicaTableProps(region="us-east-2")
    ]
)

# grantReadData only applies to the table in us-west-2 and the tableKey
global_table.grant_read_data(user)
java
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.kms.*;

User user;


App app = new App();
Stack stack = Stack.Builder.create(app, "Stack").env(Environment.builder().region("us-west-2").build()).build();

Key tableKey = new Key(stack, "Key");
Map<String, String> replicaKeyArns = Map.of(
        "us-east-1", "arn:aws:kms:us-east-1:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6",
        "us-east-2", "arn:aws:kms:us-east-2:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6");

TableV2 globalTable = TableV2.Builder.create(stack, "GlobalTable")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .encryption(TableEncryptionV2.customerManagedKey(tableKey, replicaKeyArns))
        .replicas(List.of(ReplicaTableProps.builder().region("us-east-1").build(), ReplicaTableProps.builder().region("us-east-2").build()))
        .build();

// grantReadData only applies to the table in us-west-2 and the tableKey
globalTable.grantReadData(user);
csharp
using Amazon.CDK;
using Amazon.CDK.AWS.KMS;

User user;


var app = new App();
var stack = new Stack(app, "Stack", new StackProps { Env = new Environment { Region = "us-west-2" } });

var tableKey = new Key(stack, "Key");
IDictionary<string, string> replicaKeyArns = new Dictionary<string, string> {
    { "us-east-1", "arn:aws:kms:us-east-1:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6" },
    { "us-east-2", "arn:aws:kms:us-east-2:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6" }
};

var globalTable = new TableV2(stack, "GlobalTable", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    Encryption = TableEncryptionV2.CustomerManagedKey(tableKey, replicaKeyArns),
    Replicas = new [] { new ReplicaTableProps { Region = "us-east-1" }, new ReplicaTableProps { Region = "us-east-2" } }
});

// grantReadData only applies to the table in us-west-2 and the tableKey
globalTable.GrantReadData(user);
go
import "github.com/aws/aws-cdk-go/awscdk"
import kms "github.com/aws/aws-cdk-go/awscdk"

var user User


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})

tableKey := kms.NewKey(stack, jsii.String("Key"))
replicaKeyArns := map[string]*string{
	"us-east-1": jsii.String("arn:aws:kms:us-east-1:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6"),
	"us-east-2": jsii.String("arn:aws:kms:us-east-2:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6"),
}

globalTable := dynamodb.NewTableV2(stack, jsii.String("GlobalTable"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	Encryption: dynamodb.TableEncryptionV2_CustomerManagedKey(tableKey, replicaKeyArns),
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-east-1"),
		},
		&ReplicaTableProps{
			Region: jsii.String("us-east-2"),
		},
	},
})

// grantReadData only applies to the table in us-west-2 and the tableKey
globalTable.GrantReadData(user)

The replica method can be used to grant to a specific replica table:

ts
import * as cdk from 'aws-cdk-lib';
import * as kms from 'aws-cdk-lib/aws-kms';

declare const user: iam.User;

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack', { env: { region: 'us-west-2' } });

const tableKey = new kms.Key(stack, 'Key');
const replicaKeyArns = {
  'us-east-1': 'arn:aws:kms:us-east-1:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6',
  'us-east-2': 'arn:aws:kms:us-east-2:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6',
};

const globalTable = new dynamodb.TableV2(stack, 'GlobalTable', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  encryption: dynamodb.TableEncryptionV2.customerManagedKey(tableKey, replicaKeyArns),
  replicas: [
    { region: 'us-east-1' },
    { region: 'us-east-2' },
  ],
});

// grantReadData applies to the table in us-east-2 and the key arn for the key in us-east-2
globalTable.replica('us-east-2').grantReadData(user);
python
import aws_cdk as cdk
import aws_cdk.aws_kms as kms

# user: iam.User


app = cdk.App()
stack = cdk.Stack(app, "Stack", env=cdk.Environment(region="us-west-2"))

table_key = kms.Key(stack, "Key")
replica_key_arns = {
    "us-east-1": "arn:aws:kms:us-east-1:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6",
    "us-east-2": "arn:aws:kms:us-east-2:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6"
}

global_table = dynamodb.TableV2(stack, "GlobalTable",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    encryption=dynamodb.TableEncryptionV2.customer_managed_key(table_key, replica_key_arns),
    replicas=[dynamodb.ReplicaTableProps(region="us-east-1"), dynamodb.ReplicaTableProps(region="us-east-2")
    ]
)

# grantReadData applies to the table in us-east-2 and the key arn for the key in us-east-2
global_table.replica("us-east-2").grant_read_data(user)
java
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.kms.*;

User user;


App app = new App();
Stack stack = Stack.Builder.create(app, "Stack").env(Environment.builder().region("us-west-2").build()).build();

Key tableKey = new Key(stack, "Key");
Map<String, String> replicaKeyArns = Map.of(
        "us-east-1", "arn:aws:kms:us-east-1:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6",
        "us-east-2", "arn:aws:kms:us-east-2:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6");

TableV2 globalTable = TableV2.Builder.create(stack, "GlobalTable")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .encryption(TableEncryptionV2.customerManagedKey(tableKey, replicaKeyArns))
        .replicas(List.of(ReplicaTableProps.builder().region("us-east-1").build(), ReplicaTableProps.builder().region("us-east-2").build()))
        .build();

// grantReadData applies to the table in us-east-2 and the key arn for the key in us-east-2
globalTable.replica("us-east-2").grantReadData(user);
csharp
using Amazon.CDK;
using Amazon.CDK.AWS.KMS;

User user;


var app = new App();
var stack = new Stack(app, "Stack", new StackProps { Env = new Environment { Region = "us-west-2" } });

var tableKey = new Key(stack, "Key");
IDictionary<string, string> replicaKeyArns = new Dictionary<string, string> {
    { "us-east-1", "arn:aws:kms:us-east-1:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6" },
    { "us-east-2", "arn:aws:kms:us-east-2:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6" }
};

var globalTable = new TableV2(stack, "GlobalTable", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    Encryption = TableEncryptionV2.CustomerManagedKey(tableKey, replicaKeyArns),
    Replicas = new [] { new ReplicaTableProps { Region = "us-east-1" }, new ReplicaTableProps { Region = "us-east-2" } }
});

// grantReadData applies to the table in us-east-2 and the key arn for the key in us-east-2
globalTable.Replica("us-east-2").GrantReadData(user);
go
import "github.com/aws/aws-cdk-go/awscdk"
import kms "github.com/aws/aws-cdk-go/awscdk"

var user User


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})

tableKey := kms.NewKey(stack, jsii.String("Key"))
replicaKeyArns := map[string]*string{
	"us-east-1": jsii.String("arn:aws:kms:us-east-1:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6"),
	"us-east-2": jsii.String("arn:aws:kms:us-east-2:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6"),
}

globalTable := dynamodb.NewTableV2(stack, jsii.String("GlobalTable"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	Encryption: dynamodb.TableEncryptionV2_CustomerManagedKey(tableKey, replicaKeyArns),
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-east-1"),
		},
		&ReplicaTableProps{
			Region: jsii.String("us-east-2"),
		},
	},
})

// grantReadData applies to the table in us-east-2 and the key arn for the key in us-east-2
globalTable.Replica(jsii.String("us-east-2")).GrantReadData(user)

Metrics ​

You can use metric* methods to generate metrics for a table that can be used when configuring an Alarm or Graphs. The metric* methods only apply to the primary table provisioned using the TableV2 construct. As an example, metricConsumedReadCapacityUnits used below is only for the table in us-west-2:

ts
import * as cdk from 'aws-cdk-lib';
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack', { env: { region: 'us-west-2' } });

const globalTable = new dynamodb.TableV2(stack, 'GlobalTable', {
  partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
  replicas: [
    { region: 'us-east-1' },
    { region: 'us-east-2' },
  ],
});

// metric is only for the table in us-west-2
const metric = globalTable.metricConsumedReadCapacityUnits();

new cloudwatch.Alarm(this, 'Alarm', {
  metric: metric,
  evaluationPeriods: 1,
  threshold: 1,
});
python
import aws_cdk as cdk
import aws_cdk.aws_cloudwatch as cloudwatch


app = cdk.App()
stack = cdk.Stack(app, "Stack", env=cdk.Environment(region="us-west-2"))

global_table = dynamodb.TableV2(stack, "GlobalTable",
    partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
    replicas=[dynamodb.ReplicaTableProps(region="us-east-1"), dynamodb.ReplicaTableProps(region="us-east-2")
    ]
)

# metric is only for the table in us-west-2
metric = global_table.metric_consumed_read_capacity_units()

cloudwatch.Alarm(self, "Alarm",
    metric=metric,
    evaluation_periods=1,
    threshold=1
)
java
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.cloudwatch.*;


App app = new App();
Stack stack = Stack.Builder.create(app, "Stack").env(Environment.builder().region("us-west-2").build()).build();

TableV2 globalTable = TableV2.Builder.create(stack, "GlobalTable")
        .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
        .replicas(List.of(ReplicaTableProps.builder().region("us-east-1").build(), ReplicaTableProps.builder().region("us-east-2").build()))
        .build();

// metric is only for the table in us-west-2
Metric metric = globalTable.metricConsumedReadCapacityUnits();

Alarm.Builder.create(this, "Alarm")
        .metric(metric)
        .evaluationPeriods(1)
        .threshold(1)
        .build();
csharp
using Amazon.CDK;
using Amazon.CDK.AWS.CloudWatch;


var app = new App();
var stack = new Stack(app, "Stack", new StackProps { Env = new Environment { Region = "us-west-2" } });

var globalTable = new TableV2(stack, "GlobalTable", new TablePropsV2 {
    PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
    Replicas = new [] { new ReplicaTableProps { Region = "us-east-1" }, new ReplicaTableProps { Region = "us-east-2" } }
});

// metric is only for the table in us-west-2
var metric = globalTable.MetricConsumedReadCapacityUnits();

new Alarm(this, "Alarm", new AlarmProps {
    Metric = metric,
    EvaluationPeriods = 1,
    Threshold = 1
});
go
import "github.com/aws/aws-cdk-go/awscdk"
import cloudwatch "github.com/aws/aws-cdk-go/awscdk"


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})

globalTable := dynamodb.NewTableV2(stack, jsii.String("GlobalTable"), &TablePropsV2{
	PartitionKey: &Attribute{
		Name: jsii.String("pk"),
		Type: dynamodb.AttributeType_STRING,
	},
	Replicas: []ReplicaTableProps{
		&ReplicaTableProps{
			Region: jsii.String("us-east-1"),
		},
		&ReplicaTableProps{
			Region: jsii.String("us-east-2"),
		},
	},
})

// metric is only for the table in us-west-2
metric := globalTable.MetricConsumedReadCapacityUnits()

cloudwatch.NewAlarm(this, jsii.String("Alarm"), &AlarmProps{
	Metric: metric,
	EvaluationPeriods: jsii.Number(1),
	Threshold: jsii.Number(1),
})

The replica method can be used to generate a metric for a specific replica table:

ts
import * as cdk from 'aws-cdk-lib';
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';

class FooStack extends cdk.Stack {
  public readonly globalTable: dynamodb.TableV2;

  public constructor(scope: Construct, id: string, props: cdk.StackProps) {
    super(scope, id, props);

    this.globalTable = new dynamodb.TableV2(this, 'GlobalTable', {
      partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
      replicas: [
        { region: 'us-east-1' },
        { region: 'us-east-2' },
      ],
    });
  }
}

interface BarStackProps extends cdk.StackProps {
  readonly replicaTable: dynamodb.ITableV2;
}

class BarStack extends cdk.Stack {
  public constructor(scope: Construct, id: string, props: BarStackProps) {
    super(scope, id, props);

    // metric is only for the table in us-east-1
    const metric = props.replicaTable.metricConsumedReadCapacityUnits();

    new cloudwatch.Alarm(this, 'Alarm', {
      metric: metric,
      evaluationPeriods: 1,
      threshold: 1,
    });
  }
}

const app = new cdk.App();
const fooStack = new FooStack(app, 'FooStack', { env: { region: 'us-west-2' } });
const barStack = new BarStack(app, 'BarStack', {
  replicaTable: fooStack.globalTable.replica('us-east-1'),
  env: { region: 'us-east-1' },
});
python
import aws_cdk as cdk
import aws_cdk.aws_cloudwatch as cloudwatch


class FooStack(cdk.Stack):

    def __init__(self, scope, id, *, description=None, env=None, stackName=None, tags=None, notificationArns=None, synthesizer=None, terminationProtection=None, analyticsReporting=None, crossRegionReferences=None, permissionsBoundary=None, suppressTemplateIndentation=None, propertyInjectors=None):
        super().__init__(scope, id, description=description, env=env, stackName=stackName, tags=tags, notificationArns=notificationArns, synthesizer=synthesizer, terminationProtection=terminationProtection, analyticsReporting=analyticsReporting, crossRegionReferences=crossRegionReferences, permissionsBoundary=permissionsBoundary, suppressTemplateIndentation=suppressTemplateIndentation, propertyInjectors=propertyInjectors)

        self.global_table = dynamodb.TableV2(self, "GlobalTable",
            partition_key=dynamodb.Attribute(name="pk", type=dynamodb.AttributeType.STRING),
            replicas=[dynamodb.ReplicaTableProps(region="us-east-1"), dynamodb.ReplicaTableProps(region="us-east-2")
            ]
        )

class BarStack(cdk.Stack):
    def __init__(self, scope, id, *, replicaTable, description=None, env=None, stackName=None, tags=None, notificationArns=None, synthesizer=None, terminationProtection=None, analyticsReporting=None, crossRegionReferences=None, permissionsBoundary=None, suppressTemplateIndentation=None, propertyInjectors=None):
        super().__init__(scope, id, replicaTable=replicaTable, description=description, env=env, stackName=stackName, tags=tags, notificationArns=notificationArns, synthesizer=synthesizer, terminationProtection=terminationProtection, analyticsReporting=analyticsReporting, crossRegionReferences=crossRegionReferences, permissionsBoundary=permissionsBoundary, suppressTemplateIndentation=suppressTemplateIndentation, propertyInjectors=propertyInjectors)

        # metric is only for the table in us-east-1
        metric = replica_table.metric_consumed_read_capacity_units()

        cloudwatch.Alarm(self, "Alarm",
            metric=metric,
            evaluation_periods=1,
            threshold=1
        )

app = cdk.App()
foo_stack = FooStack(app, "FooStack", env=cdk.Environment(region="us-west-2"))
bar_stack = BarStack(app, "BarStack",
    replica_table=foo_stack.global_table.replica("us-east-1"),
    env=cdk.Environment(region="us-east-1")
)
java
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.cloudwatch.*;


public class FooStack extends Stack {
    public final TableV2 globalTable;

    public FooStack(Construct scope, String id, StackProps props) {
        super(scope, id, props);

        this.globalTable = TableV2.Builder.create(this, "GlobalTable")
                .partitionKey(Attribute.builder().name("pk").type(AttributeType.STRING).build())
                .replicas(List.of(ReplicaTableProps.builder().region("us-east-1").build(), ReplicaTableProps.builder().region("us-east-2").build()))
                .build();
    }
}

public class BarStackProps extends StackProps {
    private ITableV2 replicaTable;
    public ITableV2 getReplicaTable() {
        return this.replicaTable;
    }
    public BarStackProps replicaTable(ITableV2 replicaTable) {
        this.replicaTable = replicaTable;
        return this;
    }
}

public class BarStack extends Stack {
    public BarStack(Construct scope, String id, BarStackProps props) {
        super(scope, id, props);

        // metric is only for the table in us-east-1
        Metric metric = props.replicaTable.metricConsumedReadCapacityUnits();

        Alarm.Builder.create(this, "Alarm")
                .metric(metric)
                .evaluationPeriods(1)
                .threshold(1)
                .build();
    }
}

App app = new App();
FooStack fooStack = FooStack.Builder.create(app, "FooStack").env(Environment.builder().region("us-west-2").build()).build();
BarStack barStack = new BarStack(app, "BarStack", new BarStackProps()
        .replicaTable(fooStack.globalTable.replica("us-east-1"))
        .env(Environment.builder().region("us-east-1").build())
        );
csharp
using Amazon.CDK;
using Amazon.CDK.AWS.CloudWatch;


class FooStack : Stack
{
    public TableV2 GlobalTable { get; }

    public FooStack(Construct scope, string id, StackProps props) : base(scope, id, props)
    {

        GlobalTable = new TableV2(this, "GlobalTable", new TablePropsV2 {
            PartitionKey = new Attribute { Name = "pk", Type = AttributeType.STRING },
            Replicas = new [] { new ReplicaTableProps { Region = "us-east-1" }, new ReplicaTableProps { Region = "us-east-2" } }
        });
    }
}

class BarStackProps : StackProps
{
    public ITableV2 ReplicaTable { get; set; }
}

class BarStack : Stack
{
    public BarStack(Construct scope, string id, BarStackProps props) : base(scope, id, props)
    {

        // metric is only for the table in us-east-1
        var metric = props.ReplicaTable.MetricConsumedReadCapacityUnits();

        new Alarm(this, "Alarm", new AlarmProps {
            Metric = metric,
            EvaluationPeriods = 1,
            Threshold = 1
        });
    }
}

var app = new App();
var fooStack = new FooStack(app, "FooStack", new StackProps { Env = new Environment { Region = "us-west-2" } });
var barStack = new BarStack(app, "BarStack", new BarStackProps {
    ReplicaTable = fooStack.GlobalTable.Replica("us-east-1"),
    Env = new Environment { Region = "us-east-1" }
});
go
import "github.com/aws/aws-cdk-go/awscdk"
import cloudwatch "github.com/aws/aws-cdk-go/awscdk"


type fooStack struct {
	Stack
	globalTable TableV2
}

func newFooStack(scope Construct, id *string, props StackProps) *fooStack {
	this := &fooStack{}
	cdk.NewStack_Override(this, scope, id, props)

	this.globalTable = dynamodb.NewTableV2(this, jsii.String("GlobalTable"), &TablePropsV2{
		PartitionKey: &Attribute{
			Name: jsii.String("pk"),
			Type: dynamodb.AttributeType_STRING,
		},
		Replicas: []ReplicaTableProps{
			&ReplicaTableProps{
				Region: jsii.String("us-east-1"),
			},
			&ReplicaTableProps{
				Region: jsii.String("us-east-2"),
			},
		},
	})
	return this
}

type barStackProps struct {
	StackProps
	replicaTable ITableV2
}

type barStack struct {
	Stack
}

func newBarStack(scope Construct, id *string, props barStackProps) *barStack {
	this := &barStack{}
	cdk.NewStack_Override(this, scope, id, props)

	// metric is only for the table in us-east-1
	metric := *props.replicaTable.MetricConsumedReadCapacityUnits()

	cloudwatch.NewAlarm(this, jsii.String("Alarm"), &AlarmProps{
		Metric: metric,
		EvaluationPeriods: jsii.Number(1),
		Threshold: jsii.Number(1),
	})
	return this
}

app := cdk.NewApp()
fooStack := NewFooStack(app, jsii.String("FooStack"), &StackProps{
	Env: &Environment{
		Region: jsii.String("us-west-2"),
	},
})
barStack := NewBarStack(app, jsii.String("BarStack"), &barStackProps{
	replicaTable: fooStack.globalTable.Replica(jsii.String("us-east-1")),
	env: &Environment{
		Region: jsii.String("us-east-1"),
	},
})

import from S3 Bucket ​

You can import data in S3 when creating a Table using the Table construct. To import data into DynamoDB, it is required that your data is in a CSV, DynamoDB JSON, or Amazon Ion format within an Amazon S3 bucket. The data may be compressed using ZSTD or GZIP formats, or you may choose to import it without compression. The data source can be a single S3 object or multiple S3 objects sharing a common prefix.

Further reading: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/S3DataImport.HowItWorks.html

use CSV format ​

The InputFormat.csv method accepts delimiter and headerList options as arguments. If delimiter is not specified, , is used by default. And if headerList is specified, the first line of CSV is treated as data instead of header.

ts
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack');

declare const bucket: s3.IBucket;

new dynamodb.Table(stack, 'Table', {
  partitionKey: {
    name: 'id',
    type: dynamodb.AttributeType.STRING,
  },
  importSource: {
    compressionType: dynamodb.InputCompressionType.GZIP,
    inputFormat: dynamodb.InputFormat.csv({
      delimiter: ',',
      headerList: ['id', 'name'],
    }),
    bucket,
    keyPrefix: 'prefix',
  },
});
python
import aws_cdk as cdk
import aws_cdk.aws_s3 as s3

# bucket: s3.IBucket


app = cdk.App()
stack = cdk.Stack(app, "Stack")

dynamodb.Table(stack, "Table",
    partition_key=dynamodb.Attribute(
        name="id",
        type=dynamodb.AttributeType.STRING
    ),
    import_source=dynamodb.ImportSourceSpecification(
        compression_type=dynamodb.InputCompressionType.GZIP,
        input_format=dynamodb.InputFormat.csv(
            delimiter=",",
            header_list=["id", "name"]
        ),
        bucket=bucket,
        key_prefix="prefix"
    )
)
java
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.s3.*;

IBucket bucket;


App app = new App();
Stack stack = new Stack(app, "Stack");

Table.Builder.create(stack, "Table")
        .partitionKey(Attribute.builder()
                .name("id")
                .type(AttributeType.STRING)
                .build())
        .importSource(ImportSourceSpecification.builder()
                .compressionType(InputCompressionType.GZIP)
                .inputFormat(InputFormat.csv(CsvOptions.builder()
                        .delimiter(",")
                        .headerList(List.of("id", "name"))
                        .build()))
                .bucket(bucket)
                .keyPrefix("prefix")
                .build())
        .build();
csharp
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

IBucket bucket;


var app = new App();
var stack = new Stack(app, "Stack");

new Table(stack, "Table", new TableProps {
    PartitionKey = new Attribute {
        Name = "id",
        Type = AttributeType.STRING
    },
    ImportSource = new ImportSourceSpecification {
        CompressionType = InputCompressionType.GZIP,
        InputFormat = InputFormat.Csv(new CsvOptions {
            Delimiter = ",",
            HeaderList = new [] { "id", "name" }
        }),
        Bucket = bucket,
        KeyPrefix = "prefix"
    }
});
go
import "github.com/aws/aws-cdk-go/awscdk"
import s3 "github.com/aws/aws-cdk-go/awscdk"

var bucket IBucket


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"))

dynamodb.NewTable(stack, jsii.String("Table"), &TableProps{
	PartitionKey: &Attribute{
		Name: jsii.String("id"),
		Type: dynamodb.AttributeType_STRING,
	},
	ImportSource: &ImportSourceSpecification{
		CompressionType: dynamodb.InputCompressionType_GZIP,
		InputFormat: dynamodb.InputFormat_Csv(&CsvOptions{
			Delimiter: jsii.String(","),
			HeaderList: []*string{
				jsii.String("id"),
				jsii.String("name"),
			},
		}),
		Bucket: *Bucket,
		KeyPrefix: jsii.String("prefix"),
	},
})

use DynamoDB JSON format ​

Use the InputFormat.dynamoDBJson() method to specify the inputFormat property. There are currently no options available.

ts
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack');

declare const bucket: s3.IBucket;

new dynamodb.Table(stack, 'Table', {
  partitionKey: {
    name: 'id',
    type: dynamodb.AttributeType.STRING,
  },
  importSource: {
    compressionType: dynamodb.InputCompressionType.GZIP,
    inputFormat: dynamodb.InputFormat.dynamoDBJson(),
    bucket,
    keyPrefix: 'prefix',
  },
});
python
import aws_cdk as cdk
import aws_cdk.aws_s3 as s3

# bucket: s3.IBucket


app = cdk.App()
stack = cdk.Stack(app, "Stack")

dynamodb.Table(stack, "Table",
    partition_key=dynamodb.Attribute(
        name="id",
        type=dynamodb.AttributeType.STRING
    ),
    import_source=dynamodb.ImportSourceSpecification(
        compression_type=dynamodb.InputCompressionType.GZIP,
        input_format=dynamodb.InputFormat.dynamo_db_json(),
        bucket=bucket,
        key_prefix="prefix"
    )
)
java
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.s3.*;

IBucket bucket;


App app = new App();
Stack stack = new Stack(app, "Stack");

Table.Builder.create(stack, "Table")
        .partitionKey(Attribute.builder()
                .name("id")
                .type(AttributeType.STRING)
                .build())
        .importSource(ImportSourceSpecification.builder()
                .compressionType(InputCompressionType.GZIP)
                .inputFormat(InputFormat.dynamoDBJson())
                .bucket(bucket)
                .keyPrefix("prefix")
                .build())
        .build();
csharp
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

IBucket bucket;


var app = new App();
var stack = new Stack(app, "Stack");

new Table(stack, "Table", new TableProps {
    PartitionKey = new Attribute {
        Name = "id",
        Type = AttributeType.STRING
    },
    ImportSource = new ImportSourceSpecification {
        CompressionType = InputCompressionType.GZIP,
        InputFormat = InputFormat.DynamoDBJson(),
        Bucket = bucket,
        KeyPrefix = "prefix"
    }
});
go
import "github.com/aws/aws-cdk-go/awscdk"
import s3 "github.com/aws/aws-cdk-go/awscdk"

var bucket IBucket


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"))

dynamodb.NewTable(stack, jsii.String("Table"), &TableProps{
	PartitionKey: &Attribute{
		Name: jsii.String("id"),
		Type: dynamodb.AttributeType_STRING,
	},
	ImportSource: &ImportSourceSpecification{
		CompressionType: dynamodb.InputCompressionType_GZIP,
		InputFormat: dynamodb.InputFormat_DynamoDBJson(),
		Bucket: *Bucket,
		KeyPrefix: jsii.String("prefix"),
	},
})

use Amazon Ion format ​

Use the InputFormat.ion() method to specify the inputFormat property. There are currently no options available.

ts
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'Stack');

declare const bucket: s3.IBucket;

new dynamodb.Table(stack, 'Table', {
  partitionKey: {
    name: 'id',
    type: dynamodb.AttributeType.STRING,
  },
  importSource: {
    compressionType: dynamodb.InputCompressionType.GZIP,
    inputFormat: dynamodb.InputFormat.ion(),
    bucket,
    keyPrefix: 'prefix',
  },
});
python
import aws_cdk as cdk
import aws_cdk.aws_s3 as s3

# bucket: s3.IBucket


app = cdk.App()
stack = cdk.Stack(app, "Stack")

dynamodb.Table(stack, "Table",
    partition_key=dynamodb.Attribute(
        name="id",
        type=dynamodb.AttributeType.STRING
    ),
    import_source=dynamodb.ImportSourceSpecification(
        compression_type=dynamodb.InputCompressionType.GZIP,
        input_format=dynamodb.InputFormat.ion(),
        bucket=bucket,
        key_prefix="prefix"
    )
)
java
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.s3.*;

IBucket bucket;


App app = new App();
Stack stack = new Stack(app, "Stack");

Table.Builder.create(stack, "Table")
        .partitionKey(Attribute.builder()
                .name("id")
                .type(AttributeType.STRING)
                .build())
        .importSource(ImportSourceSpecification.builder()
                .compressionType(InputCompressionType.GZIP)
                .inputFormat(InputFormat.ion())
                .bucket(bucket)
                .keyPrefix("prefix")
                .build())
        .build();
csharp
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

IBucket bucket;


var app = new App();
var stack = new Stack(app, "Stack");

new Table(stack, "Table", new TableProps {
    PartitionKey = new Attribute {
        Name = "id",
        Type = AttributeType.STRING
    },
    ImportSource = new ImportSourceSpecification {
        CompressionType = InputCompressionType.GZIP,
        InputFormat = InputFormat.Ion(),
        Bucket = bucket,
        KeyPrefix = "prefix"
    }
});
go
import "github.com/aws/aws-cdk-go/awscdk"
import s3 "github.com/aws/aws-cdk-go/awscdk"

var bucket IBucket


app := cdk.NewApp()
stack := cdk.NewStack(app, jsii.String("Stack"))

dynamodb.NewTable(stack, jsii.String("Table"), &TableProps{
	PartitionKey: &Attribute{
		Name: jsii.String("id"),
		Type: dynamodb.AttributeType_STRING,
	},
	ImportSource: &ImportSourceSpecification{
		CompressionType: dynamodb.InputCompressionType_GZIP,
		InputFormat: dynamodb.InputFormat_Ion(),
		Bucket: *Bucket,
		KeyPrefix: jsii.String("prefix"),
	},
})

Types ​

NameKindSummary
TableConstruct (L2)Provides a DynamoDB table.
TableBaseConstruct (L2)
TableBaseV2Construct (L2)Base class for a DynamoDB table.
TableV2Construct (L2)A DynamoDB Table.
TableV2MultiAccountReplicaConstruct (L2)A multi-account replica of a DynamoDB table.
CfnGlobalTableConstruct (L1)The AWS::DynamoDB::GlobalTable resource enables you to create and manage a Version 2019.11.21 global table. This resource cannot be used to create or manage a Version 2017.11.29 global table. For more information, see Global tables .
CfnTableConstruct (L1)The AWS::DynamoDB::Table resource creates a DynamoDB table. For more information, see CreateTable in the Amazon DynamoDB API Reference .
ApproximateCreationDateTimePrecisionEnumThe precision associated with the DynamoDB write timestamps that will be replicated to Kinesis.
AttributeStructRepresents an attribute for describing the key schema for the table and indexes.
AttributeTypeEnumData types for attributes within a table.
AutoscaledCapacityOptionsStructOptions used to configure autoscaled capacity.
BillingClassRepresents how capacity is managed and how you are charged for read and write throughput for a DynamoDB table.
BillingModeEnumDynamoDB's Read/Write capacity modes.
CapacityClassRepresents the amount of read and write operations supported by a DynamoDB table.
CapacityModeEnumCapacity modes.
CfnGlobalTable.AttributeDefinitionPropertyStructRepresents an attribute for describing the schema for the table and indexes.
CfnGlobalTable.CapacityAutoScalingSettingsPropertyStructConfigures a scalable target and an autoscaling policy for a table or global secondary index's read or write capacity.
CfnGlobalTable.ContributorInsightsSpecificationPropertyStructConfigures contributor insights settings for a replica or one of its indexes.
CfnGlobalTable.GlobalReadProvisionedThroughputSettingsPropertyStruct
CfnGlobalTable.GlobalSecondaryIndexPropertyStructAllows you to specify a global secondary index for the global table.
CfnGlobalTable.GlobalTableWitnessPropertyStructThe witness Region for the MRSC global table.
CfnGlobalTable.KeySchemaPropertyStructRepresents a single element of a key schema.
CfnGlobalTable.KinesisStreamSpecificationPropertyStructThe Kinesis Data Streams configuration for the specified global table replica.
CfnGlobalTable.LocalSecondaryIndexPropertyStructRepresents the properties of a local secondary index.
CfnGlobalTable.PointInTimeRecoverySpecificationPropertyStructRepresents the settings used to enable point in time recovery.
CfnGlobalTable.ProjectionPropertyStructRepresents attributes that are copied (projected) from the table into an index.
CfnGlobalTable.ReadOnDemandThroughputSettingsPropertyStructSets the read request settings for a replica table or a replica global secondary index.
CfnGlobalTable.ReadProvisionedThroughputSettingsPropertyStructAllows you to specify the read capacity settings for a replica table or a replica global secondary index when the BillingMode is set to PROVISIONED .
CfnGlobalTable.ReplicaGlobalSecondaryIndexSpecificationPropertyStructRepresents the properties of a global secondary index that can be set on a per-replica basis.
CfnGlobalTable.ReplicaSpecificationPropertyStructDefines settings specific to a single replica of a global table.
CfnGlobalTable.ReplicaSSESpecificationPropertyStructAllows you to specify a KMS key identifier to be used for server-side encryption.
CfnGlobalTable.ReplicaStreamSpecificationPropertyStructRepresents the DynamoDB Streams configuration for a global table replica.
CfnGlobalTable.ResourcePolicyPropertyStructCreates or updates a resource-based policy document that contains the permissions for DynamoDB resources, such as a table, its indexes, and stream.
CfnGlobalTable.SearchSchemaElementPropertyStruct
CfnGlobalTable.SSESpecificationPropertyStructRepresents the settings used to enable server-side encryption.
CfnGlobalTable.StreamSpecificationPropertyStructRepresents the DynamoDB Streams configuration for a table in DynamoDB .
CfnGlobalTable.TargetTrackingScalingPolicyConfigurationPropertyStructDefines a target tracking scaling policy.
CfnGlobalTable.TimeToLiveSpecificationPropertyStructRepresents the settings used to enable or disable Time to Live (TTL) for the specified table.
CfnGlobalTable.VectorAttributePropertyStruct
CfnGlobalTable.VectorIndexPropertyStruct
CfnGlobalTable.WarmThroughputPropertyStructProvides visibility into the number of read and write operations your table or secondary index can instantaneously support.
CfnGlobalTable.WriteOnDemandThroughputSettingsPropertyStructSets the write request settings for a global table or a global secondary index.
CfnGlobalTable.WriteProvisionedThroughputSettingsPropertyStructSpecifies an auto scaling policy for write capacity.
CfnGlobalTablePropsStructProperties for defining a CfnGlobalTable.
CfnTable.AttributeDefinitionPropertyStructRepresents an attribute for describing the schema for the table and indexes.
CfnTable.ContributorInsightsSpecificationPropertyStructConfigures contributor insights settings for a table or one of its indexes.
CfnTable.CsvPropertyStructThe options for imported source files in CSV format.
CfnTable.GlobalSecondaryIndexPropertyStructRepresents the properties of a global secondary index.
CfnTable.ImportSourceSpecificationPropertyStructSpecifies the properties of data being imported from the S3 bucket source to the table.
CfnTable.InputFormatOptionsPropertyStructThe format options for the data that was imported into the target table.
CfnTable.KeySchemaPropertyStructRepresents a single element of a key schema.
CfnTable.KinesisStreamSpecificationPropertyStructThe Kinesis Data Streams configuration for the specified table.
CfnTable.LocalSecondaryIndexPropertyStructRepresents the properties of a local secondary index.
CfnTable.OnDemandThroughputPropertyStructSets the maximum number of read and write units for the specified on-demand table.
CfnTable.PointInTimeRecoverySpecificationPropertyStructThe settings used to enable point in time recovery.
CfnTable.ProjectionPropertyStructRepresents attributes that are copied (projected) from the table into an index.
CfnTable.ProvisionedThroughputPropertyStructThroughput for the specified table, which consists of values for ReadCapacityUnits and WriteCapacityUnits .
CfnTable.ResourcePolicyPropertyStructCreates or updates a resource-based policy document that contains the permissions for DynamoDB resources, such as a table, its indexes, and stream.
CfnTable.S3BucketSourcePropertyStructThe S3 bucket that is being imported from.
CfnTable.SearchSchemaElementPropertyStruct
CfnTable.SSESpecificationPropertyStructRepresents the settings used to enable server-side encryption.
CfnTable.StreamSpecificationPropertyStructRepresents the DynamoDB Streams configuration for a table in DynamoDB.
CfnTable.TimeToLiveSpecificationPropertyStructRepresents the settings used to enable or disable Time to Live (TTL) for the specified table.
CfnTable.VectorAttributePropertyStruct
CfnTable.VectorIndexPropertyStruct
CfnTable.WarmThroughputPropertyStructProvides visibility into the number of read and write operations your table or secondary index can instantaneously support.
CfnTablePropsStructProperties for defining a CfnTable.
ContributorInsightsModeEnumDynamoDB's Contributor Insights Mode.
ContributorInsightsSpecificationStructReference to ContributorInsightsSpecification.
CsvOptionsStructThe options for imported source files in CSV format.
EnableScalingPropsStructProperties for enabling DynamoDB capacity scaling.
GlobalSecondaryIndexPropsStructProperties for a global secondary index.
GlobalSecondaryIndexPropsV2StructProperties used to configure a global secondary index.
GlobalTableSettingsReplicationModeEnumThe replication mode for global table settings across multiple accounts.
ImportSourceSpecificationStructProperties for importing data from the S3.
InputCompressionTypeEnumType of compression to use for imported data.
InputFormatClassThe format of the source data.
IScalableTableAttributeInterfaceInterface for scalable attributes.
ITableInterfaceAn interface that represents a DynamoDB Table - either created with the CDK, or an existing one.
ITableV2InterfaceRepresents an instance of a DynamoDB table.
KeySchemaStructA description of a key schema of an LSI, GSI or Table.
LocalSecondaryIndexPropsStructProperties for a local secondary index.
MaxThroughputPropsStructProperties used to configure maximum throughput for an on-demand table.
MultiRegionConsistencyEnumGlobal table multi-region consistency mode.
OperationEnumSupported DynamoDB table operations.
OperationsMetricOptionsStructOptions for configuring metrics that considers multiple operations.
PointInTimeRecoverySpecificationStructReference to PointInTimeRecovey Specification for continuous backups.
ProjectionTypeEnumThe set of attributes that are projected into the index.
ReplicaGlobalSecondaryIndexOptionsStructOptions used to configure global secondary indexes on a replica table.
ReplicaTablePropsStructProperties used to configure a replica table.
SchemaOptionsStructRepresents the table schema attributes.
SecondaryIndexPropsStructProperties for a secondary index.
StreamGrantsClassA set of permissions to grant on a Table Stream.
StreamGrantsPropsStructConstruction properties for StreamGrants.
StreamViewTypeEnumWhen an item in the table is modified, StreamViewType determines what information is written to the stream for this table.
SystemErrorsForOperationsMetricOptionsStructOptions for configuring a system errors metric that considers multiple operations.
TableAttributesStructReference to a dynamodb table.
TableAttributesV2StructAttributes of a DynamoDB table.
TableClassEnumDynamoDB's table class.
TableEncryptionEnumWhat kind of server-side encryption to apply to this table.
TableEncryptionV2ClassRepresents server-side encryption for a DynamoDB table.
TableGrantsFacadeA set of permissions to grant on a Table.
TableGrantsPropsStructConstruction properties for TableGrants.
TableOptionsStructProperties of a DynamoDB Table.
TableOptionsV2StructOptions used to configure a DynamoDB table.
TablePropsStructProperties for a DynamoDB Table.
TablePropsV2StructProperties used to configure a DynamoDB table.
TableV2MultiAccountReplicaPropsStructProperties for creating a multi-account replica table.
ThroughputPropsStructProperties used to configure provisioned throughput for a DynamoDB table.
UtilizationScalingPropsStructProperties for enabling DynamoDB utilization tracking.
WarmThroughputStructReference to WarmThroughput for a DynamoDB table.