AWS DynamoDB ExecModule
Overview
AwsDynamoDbModule connects ValkyrAI workflows to Amazon DynamoDB through the bundled AWS SDK v2 client. It covers n8n's core DynamoDB item operations while adding table discovery, table metadata, native DynamoDB attribute types, bounded pagination, verified IntegrationAccount credentials, annotation-backed Workflow Studio discovery, and conservative replay behavior for writes.
The connector implements eight operations:
- discovery:
list_tables,describe_table - reads:
get_item,query,scan - mutations:
put_item,update_item,delete_item
Table lifecycle, batch and transactional APIs, streams, TTL management, PartiQL, DAX, import/export, and backup operations are intentionally outside this first governed surface.
Usage
- Create a dedicated AWS IAM principal scoped to the exact DynamoDB tables and indexes the workflow needs.
- Store its access key ID and secret access key in an AWS
IntegrationAccount, verify the account, and keep it inREADYstatus. - Add
AwsDynamoDbModuleto a workflow and bind the account throughExecModuleConfig.authConfig.integrationAccount. - Set
operation,region,tableName, and the operation-specific key, item, expression, or pagination fields. - Preserve returned keys and AWS request IDs. For any ambiguous mutation response, inspect current table state before replaying the write.
Never place AWS credentials in mapped input, item attributes, logs, or examples. Credential-like input fields are rejected before provider access.
Inputs
| Name | Type | Required for | Default | Constraints |
|---|---|---|---|---|
operation | string | Every execution | None | One of the eight documented operations. |
region | string | Every execution | None | AWS region syntax such as us-west-2; custom endpoints are not accepted. |
tableName | string | All except list_tables | None | DynamoDB table-name syntax, 3-255 characters. |
key | object | get_item, update_item, delete_item | None | One or two non-empty string, number, or $binary attributes. |
item | object | put_item | None | Non-empty natural JSON item, bounded to DynamoDB's 400 KiB item limit. |
indexName | string | Optional query or scan | None | Local or global secondary index name. |
keyConditionExpression | string | query | None | DynamoDB key condition, at most 4,096 characters. |
filterExpression | string | Optional query or scan | None | DynamoDB filter expression, at most 4,096 characters. |
updateExpression | string | update_item | None | DynamoDB update expression, at most 4,096 characters. |
conditionExpression | string | Optional mutation | None | Conditional-write guard, at most 4,096 characters. |
projectionExpression | string | Optional read | None | Attribute projection, at most 4,096 characters. |
expressionAttributeNames | object | Optional expression | {} | At most 255 #alias entries. |
expressionAttributeValues | object | Optional expression | {} | At most 255 :value entries using the item value notation below. |
exclusiveStartKey | object | Optional query or scan resume | None | Opaque nextKey from a prior response. |
nextToken | string | Optional list_tables resume | None | Opaque AWS table-name continuation. |
limit | integer | List, query, or scan | 100 | 1-10,000 returned tables or items. |
pageSize | integer | Query or scan | 100 | 1-1,000 provider evaluations per request. |
returnAll | boolean | List, query, or scan | false | Follow pages until exhaustion, limit, or the 100-page guard. |
consistentRead | boolean | get_item, query, or scan | false | Requests a strong read where DynamoDB supports it. |
scanIndexForward | boolean | query | true | Ascending sort-key order when true. |
returnValues | string | Mutation | NONE | Put/delete: NONE or ALL_OLD; update also supports UPDATED_OLD, ALL_NEW, and UPDATED_NEW. |
confirmDelete | boolean | delete_item | false | Must be explicitly true before deletion. |
Natural JSON strings, booleans, numbers, nulls, arrays, and objects map to DynamoDB S, BOOL, N, NULL, L, and M. Use a single-key tagged object for types JSON cannot express directly:
{
"binary": {"$binary": "AQI="},
"roles": {"$stringSet": ["planner", "worker"]},
"scores": {"$numberSet": [1, 2.5]},
"blobs": {"$binarySet": ["AQ==", "Ag=="]}
}
Sets must be non-empty and contain unique values. Numbers are normalized without precision loss and must fit DynamoDB's 38-digit numeric range.
Outputs
Every execution returns stable status, operation, and attempts fields.
| Name | Type | When present | Description |
|---|---|---|---|
status | string | Always | success or error. |
operation | string | Always | Normalized operation. |
attempts | integer | Always | Provider calls, including safe read retries and pages. |
data | object | Item, table, or mutation success | Normalized result and optional returned attributes. |
items | array | List, query, or scan success | Bounded table or decoded item results. |
count | integer | List, query, or scan success | Number of returned rows. |
scannedCount | integer | Query or scan success | Provider-evaluated row count across fetched pages. |
hasMore | boolean | Paginated read success | Whether another provider page exists. |
nextToken | string | Another table-list page exists | Opaque continuation for list_tables. |
nextKey | object | Another query/scan page exists | Decoded opaque key for exclusiveStartKey. |
requestId | string | AWS supplies one | Bounded provider reference for reconciliation and support. |
error | object | Failure | Safe {code, message, httpStatus?, retryable} details. |
Items may contain confidential application state. Do not log or forward keys, attributes, continuation keys, or returned images to unapproved destinations.
IntegrationAccount Requirements
Bind one AWS IntegrationAccount through the normalized ExecModule authentication relationship:
| Field | Requirement |
|---|---|
| Provider | Amazon Web Services / DynamoDB |
status | Must be READY. |
verified | Must be true. |
apiKey SecureField | AWS access key ID. |
password SecureField | AWS secret access key. |
Grant only the actions used by the workflow:
dynamodb:ListTablesforlist_tablesdynamodb:DescribeTablefordescribe_tabledynamodb:GetItemforget_itemdynamodb:Queryforquerydynamodb:Scanforscandynamodb:PutItemforput_itemdynamodb:UpdateItemforupdate_itemdynamodb:DeleteItemfordelete_item
Restrict item and query actions to exact table and index ARNs. ListTables is the only operation here that AWS does not resource-scope. The current connector supports a long-lived access-key pair. Temporary session credentials, role assumption, cross-account role chaining, and caller-supplied credentials are deferred.
Configuration
The awsAccount relationship is the only credential configuration. Operation, region, table, expressions, and pagination belong in module parameters or mapped input; read retries use the normalized retry policy.
{
"version": "1.0.0",
"authConfig": {
"authStrategy": 1,
"integrationAccount": "integration-account:aws-dynamodb-production"
},
"retryPolicy": {
"maxAttempts": 3
},
"payloadConfig": {
"parameters": "{\"operation\":\"query\",\"region\":\"us-west-2\",\"tableName\":\"workflow-state\",\"keyConditionExpression\":\"tenantId = :tenant\"}"
}
}
The relationship value is illustrative. Persisted workflows bind the generated IntegrationAccount relationship, never plaintext credentials.
Operations
| Operation | Provider behavior | Side effect and retry behavior |
|---|---|---|
list_tables | Lists region tables using opaque table-name pagination. | Read-only; transient failures retry within the configured bound. |
describe_table | Reads key schema, attribute definitions, status, size, indexes, and protection state. | Read-only; transient failures retry. Counts and sizes are approximate. |
get_item | Reads one exact primary key with optional projection and strong consistency. | Read-only; transient failures retry. |
query | Evaluates one table or index key condition with optional filter and projection. | Read-only; transient failures retry; pagination is bounded. |
scan | Evaluates bounded table or index pages with optional filter and projection. | Read-only but potentially capacity-intensive; transient failures retry. |
put_item | Writes one complete item with an optional condition. | External write; exactly one provider attempt. |
update_item | Applies one update expression with an optional condition. | External write; exactly one provider attempt. |
delete_item | Deletes one exact primary key with an optional condition. | Destructive; requires confirmDelete=true; exactly one provider attempt. |
Errors and Failure Modes
| Code | Typical cause | Retryable | Resolution |
|---|---|---|---|
VALIDATION_ERROR | Missing or invalid table, key, item, expression, native type, bound, or delete confirmation. | No | Correct the named input; no provider request was sent. |
UNSUPPORTED_OPERATION | Unknown operation. | No | Select a documented operation. |
INTEGRATION_ACCOUNT_ERROR | Account missing, unverified, not READY, or missing key material. | No | Repair and bind the AWS account. |
AWS_DYNAMODB_HTTP_400 | Invalid expression, key mismatch, failed condition, or exceeded capacity. | Provider-dependent | Inspect the current item and request ID before deciding whether to retry. |
AWS_DYNAMODB_HTTP_403 | IAM denies the action. | No | Grant only the missing action on the intended table or index. |
AWS_DYNAMODB_HTTP_404 | Table or index is absent or invisible. | No | Verify region, account, and exact resource name. |
AWS_DYNAMODB_HTTP_429 / 503 | Transient provider pressure. | Yes for reads only | Reads can retry; reconcile all mutations before replay. |
NETWORK_ERROR | DNS, TLS, timeout, or connectivity failure. | Yes for reads only | Treat mutation outcomes as ambiguous and inspect current item state. |
EXECUTION_ERROR | Unexpected bounded runtime failure. | No automatic replay | Preserve table, key, condition, and request ID for reconciliation. |
Provider exception text is not copied into output, preventing credential echoes and unbounded error payloads.
Example
Conditionally advance durable workflow state:
{
"operation": "update_item",
"region": "us-west-2",
"tableName": "workflow-state",
"key": {"jobId": "job-123"},
"updateExpression": "SET #state = :next, #version = :newVersion",
"conditionExpression": "#version = :expectedVersion",
"expressionAttributeNames": {
"#state": "state",
"#version": "version"
},
"expressionAttributeValues": {
":next": "ready",
":newVersion": 3,
":expectedVersion": 2
},
"returnValues": "ALL_NEW"
}
Expected result shape:
{
"status": "success",
"operation": "update_item",
"attempts": 1,
"requestId": "aws-request-reference",
"data": {
"tableName": "workflow-state",
"updated": true,
"attributes": {
"jobId": "job-123",
"state": "ready",
"version": 3
}
}
}
Notes
- Pagination:
list_tablespreserves AWS table-name tokens.queryandscanexpose the last evaluated key asnextKey.returnAll=truestops atlimit, resource exhaustion, or 100 provider pages. - Capacity:
pageSizebounds items evaluated per provider request; filters run after DynamoDB reads items and therefore do not reduce consumed read capacity. Preferquerytoscan, use narrow projections, and size provisioned/on-demand capacity independently. - API limits: items are bounded at 400 KiB, result accumulation at 10,000 items, expressions at 4,096 characters, maps at 32 nested levels, and expression maps at 255 entries.
- Consistency: strongly consistent reads are not supported on global secondary indexes. The module forwards the requested mode and surfaces the provider rejection safely.
- Retry policy: HTTP 408, 429, 500, 502, 503, and 504 plus network failures can retry only for reads, bounded by
RetryPolicy.maxAttemptsfrom 1 through 5. AWS SDK retries are disabled so module accounting and single-attempt writes remain deterministic. - Idempotency: reads are safe to retry. Mutations are single-attempt because network failures can leave an ambiguous outcome. Use
conditionExpressionwith a version or absence check, then read current state before replaying. - Destructive behavior:
delete_itempermanently removes the item identified by the exact primary key and requires explicit confirmation. Table deletion is not exposed. - Data handling: item keys, values, returned images, and continuation keys are confidential. The module never logs request or response bodies.
- Provider verification boundary: deterministic tests cover validation, fixed routing, account isolation, native types, request mapping, pagination, read retries, mutation replay boundaries, normalization, redaction, registration, and delete confirmation. Live AWS behavior remains unverified until an authorized DynamoDB credential and reviewed test table are supplied.
- Functional reference: n8n's AWS DynamoDB node centers on get, get-all, upsert, and delete item workflows, including query-versus-scan selection and expressions. ValkyrAI adds discovery, table metadata, explicit put versus update semantics, native type preservation, verified account enforcement, bounded outputs, and conservative single-attempt writes.
- Runtime boundary: merged source and published documentation do not update the deployed Workflow Studio catalog until a ValkyrAI backend release exposes
AwsDynamoDbModulethrough/v1/modules/metadata.