Microsoft SQL Server & Azure SQL

Detailed information on the Microsoft SQL Server state store component

Component format

This state store component can be used with both Microsoft SQL Server and Azure SQL.

To set up this state store, create a component of type state.sqlserver. See this guide on how to create and apply a state store configuration.

  1. apiVersion: dapr.io/v1alpha1
  2. kind: Component
  3. metadata:
  4. name: <NAME>
  5. spec:
  6. type: state.sqlserver
  7. version: v1
  8. metadata:
  9. # Authenticate using SQL Server credentials
  10. - name: connectionString
  11. value: |
  12. Server=myServerName\myInstanceName;Database=myDataBase;User Id=myUsername;Password=myPassword;
  13. # Authenticate with Azure AD (Azure SQL only)
  14. # "useAzureAD" be set to "true"
  15. - name: useAzureAD
  16. value: true
  17. # Connection string or URL of the Azure SQL database, optionally containing the database
  18. - name: connectionString
  19. value: |
  20. sqlserver://myServerName.database.windows.net:1433?database=myDataBase
  21. # Other optional fields (listing default values)
  22. - name: tableName
  23. value: "state"
  24. - name: metadataTableName
  25. value: "dapr_metadata"
  26. - name: schema
  27. value: "dbo"
  28. - name: keyType
  29. value: "string"
  30. - name: keyLength
  31. value: "200"
  32. - name: indexedProperties
  33. value: ""
  34. - name: cleanupIntervalInSeconds
  35. value: "3600"

Warning

The above example uses secrets as plain strings. It is recommended to use a secret store for the secrets as described here.

If you wish to use SQL server as an actor state store, append the following to the metadata:

  1. - name: actorStateStore
  2. value: "true"

Spec metadata fields

Authenticate using SQL Server credentials

The following metadata options are required to authenticate using SQL Server credentials. This is supported on both SQL Server and Azure SQL.

FieldRequiredDetailsExample
connectionStringYThe connection string used to connect.
If the connection string contains the database, it must already exist. Otherwise, if the database is omitted, a default database named “Dapr” is created.
“Server=myServerName\myInstanceName;Database=myDataBase;User Id=myUsername;Password=myPassword;”

Authenticate using Azure AD

Authenticating with Azure AD is supported with Azure SQL only. All authentication methods supported by Dapr can be used, including client credentials (“service principal”) and Managed Identity.

FieldRequiredDetailsExample
useAzureADYMust be set to true to enable the component to retrieve access tokens from Azure AD.“true”
connectionStringYThe connection string or URL of the Azure SQL database, without credentials.
If the connection string contains the database, it must already exist. Otherwise, if the database is omitted, a default database named “Dapr” is created.
“sqlserver://myServerName.database.windows.net:1433?database=myDataBase”
azureTenantIdNID of the Azure AD tenant“cd4b2887-304c-47e1-b4d5-65447fdd542b”
azureClientIdNClient ID (application ID)“c7dd251f-811f-4ba2-a905-acd4d3f8f08b”
azureClientSecretNClient secret (application password)“Ecy3XG7zVZK3/vl/a2NSB+a1zXLa8RnMum/IgD0E”

Other metadata options

FieldRequiredDetailsExample
tableNameNThe name of the table to use. Alpha-numeric with underscores. Defaults to “state”“table_name”
metadataTableNameNName of the table Dapr uses to store a few metadata properties. Defaults to dapr_metadata.“dapr_metadata”
keyTypeNThe type of key used. Supported values: “string” (default), “uuid”, “integer”.“string”
keyLengthNThe max length of key. Ignored if “keyType” is not string. Defaults to “200”“200”
schemaNThe schema to use. Defaults to “dbo”“dapr”,“dbo”
indexedPropertiesNList of indexed properties, as a string containing a JSON document.‘[{“column”: “transactionid”, “property”: “id”, “type”: “int”}, {“column”: “customerid”, “property”: “customer”, “type”: “nvarchar(100)”}]’
actorStateStoreNIndicates that Dapr should configure this component for the actor state store (more information).“true”
cleanupIntervalInSecondsNInterval, in seconds, to clean up rows with an expired TTL. Default: “3600” (i.e. 1 hour). Setting this to values <=0 disables the periodic cleanup.“1800”, “-1”

Create a Microsoft SQL Server/Azure SQL instance

Follow the instructions from the Azure documentation on how to create a SQL database. The database must be created before Dapr consumes it.

In order to setup SQL Server as a state store, you need the following properties:

  • Connection String: The SQL Server connection string. For example: server=localhost;user id=sa;password=your-password;port=1433;database=mydatabase;
  • Schema: The database schema to use (default=dbo). Will be created if does not exist
  • Table Name: The database table name. Will be created if does not exist
  • Indexed Properties: Optional properties from json data which will be indexed and persisted as individual column

Create a dedicated user

When connecting with a dedicated user (not sa), these authorizations are required for the user - even when the user is owner of the desired database schema:

  • CREATE TABLE
  • CREATE TYPE

TTLs and cleanups

This state store supports Time-To-Live (TTL) for records stored with Dapr. When storing data using Dapr, you can set the ttlInSeconds metadata property to indicate after how many seconds the data should be considered “expired”.

Because SQL Server doesn’t have built-in support for TTLs, Dapr implements this by adding a column in the state table indicating when the data should be considered “expired”. “Expired” records are not returned to the caller, even if they’re still physically stored in the database. A background “garbage collector” periodically scans the state table for expired rows and deletes them.

You can set the interval for the deletion of expired records with the cleanupIntervalInSeconds metadata property, which defaults to 3600 seconds (that is, 1 hour).

  • Longer intervals require less frequent scans for expired rows, but can require storing expired records for longer, potentially requiring more storage space. If you plan to store many records in your state table, with short TTLs, consider setting cleanupIntervalInSeconds to a smaller value - for example, 300 (300 seconds, or 5 minutes).
  • If you do not plan to use TTLs with Dapr and the SQL Server state store, you should consider setting cleanupIntervalInSeconds to a value <= 0 (e.g. 0 or -1) to disable the periodic cleanup and reduce the load on the database.

The state store does not have an index on the ExpireDate column, which means that each clean up operation must perform a full table scan. If you intend to write to the table with a large number of records that use TTLs, you should consider creating an index on the ExpireDate column. An index makes queries faster, but uses more storage space and slightly slows down writes.

  1. CREATE CLUSTERED INDEX expiredate_idx ON state(ExpireDate ASC)

Last modified October 12, 2023: Update config.toml (#3826) (0ffc2e7)