Skip to main content

dynamodb: Interacting with a DynamoDB database | Enterprise OPA

The dynamodb built-in functions allow you to interact with a DynamoDB database.

Shared Parameters

ParameterTypeRequiredDefaultDescription
endpointStringNoDynamoDB region-specific endpointThe endpoint of the DynamoDB service.
regionStringYesThe AWS region of the DynamoDB service.
credentialsObjectNoSee Credentials.
cacheBoolNofalseCache the results of queries.
cache_durationIntegerNo60Duration (in seconds) to keep cached query results.
raise_errorBoolNotrueSee Errors

Credentials

Credentials for AWS calls are checked in the following order:

  1. Statically provided credentials (see below)
  2. Standard AWS environment variables (see below)
  3. ECS/EC2 role provider
ParameterTypeRequiredDefaultDescription
credentials.access_keyStringNoAWS_ACCESS_KEY_ID environment variableAWS Access key ID. If provided in Rego, must also provided credentials.secret_key
credentials.secret_keyStringNoAWS_SECRET_ACCESS_KEY environment variableAWS Secret Access Key. If provided in Rego, must also provide credentials.access_key
credentials.session_tokenStringNoAWS_SESSION_TOKEN environment variableAWS Session Token.

Errors

By default—and if raise_error is true—then an error returned will halt policy evaluation.

If raise_error is false, then the response object contains the error in an error key instead of its usual response.

{
"error": ...
}

dynamodb.get

dynamodb.get executes a get against a DynamoDB database, returning a single row.

Example usage

thread := dynamodb.get({
"endpoint": "dynamodb.us-west-2.amazonaws.com",
"region": "us-west-2",
"table": "thread",
"key": {
"ForumName": {"S": "help"},
"Subject": {"S": "How to write rego"}
}
}) # => { "row": ...}

Parameters

ParameterTypeRequiredDefaultDescription
tableStringYesName of the table to query.
keyObjectYesComplex object representing the key to retrieve from the table. See AWS example tables and data.
consistent_readBoolNofalseIf true, a strongly consistent read is used; if false, an eventually consistent read is used.

dynamodb.query

dynamodb.query makes a query against a DynamoDB database, returning multiple rows.

Example usage

See the DynamoDB getting started guide for details on the data.

music := dynamodb.query({
"region": "us-west-1",
"table": "foo",
"key_condition_expression": "#music = :name",
"expression_attribute_values": {":name": {"S": "Acme Band"}},
"expression_attribute_names": {"#music": "Artist"}
}) # => { "rows": ... }

Parameters

See the AWS SDK for information about each individual parameter.

ParameterTypeRequiredDefaultDescription
tableStringYesName of the table to query.
consistent_readBoolNofalseIf true, a strongly consistent read is used; if false, an eventually consistent read is used.
key_condition_expressionStringYes
expression_attribute_namesObjectNo
expression_attribute_valuesObjectNo
exclusive_start_keyObjectNo
index_nameStringNo""
limitIntegerNo0
projection_expressionStringNo""
scan_index_forwardBooleanNotrue
selectStringNo""

Utility helpers

Enterprise OPA comes with helper methods for using these built-ins together with vault.send: dynamodb.get and dynamodb.query.

Both of these methods are available in Enterprise OPA at data.system.eopa.utils.dynamodb.v1.vault.

package example
import data.system.eopa.utils.dynamodb.v1.vault as dynamodb

example_1 := dynamodb.get({"table": "foo", "key": {"p": {"S": "x"}, "s": {"N": "1"}}})
) # => {"row": { ... }}

example_2 := dynamodb.query({"table": "foo", "key_condition_expression": "#p = :value", "expression_attribute_values": {":value": {"S": "x"}}, "expression_attribute_names": {"#p": "p"}})
) # => {"rows": [ ... ]}

The utility methods will lookup connection data from a map it expects to find in Vault, under the path secret/dynamodb:

{
"region": "...",
"endpoint": "...",
"access_key": "...",
"secret_key": "...",
}

Of those, only region is mandatory, see the parameter docs above.

To override the secret path within Vault, use:

package example
import data.system.eopa.utils.dynamodb.v1.vault as dynamodb

dynamodb_query(req) := result {
result := dynamodb.query(req)
with dynamodb.override.secret_path as "secret/prod/eopa-dynamodb"

example_3 := dynamodb_query({"table": "foo", "key_condition_expression": "#p = :value", "expression_attribute_values": {":value": {"S": "x"}}, "expression_attribute_names": {"#p": "p"}})
) # => {"rows": [ ... ]}

Override for a dynamodb.get is similar. If you need to override the Vault address or token, you can use this:

package example
import data.system.eopa.utils.vault.v1.env as vault
import data.system.eopa.utils.dynamodb.v1.vault as dynamodb

dynamodb_query(req) := result {
result := dynamodb.query(req)
with dynamodb.override.secret_path as "secret/prod/eopa-dynamodb"
with vault.override.address as "localhost"
with vault.override.token as "dev-token-2"

example_4 := dynamodb_query({"table": "foo", "key_condition_expression": "#p = :value", "expression_attribute_values": {":value": {"S": "x"}}, "expression_attribute_names": {"#p": "p"}})
) # => {"rows": [ ... ]}

To control the caching and error raising behavior, cache, cache_duration, and raise_error can also be passed to dynamodb.get and dynamodb.query as keys of their request objects.