Dynamic configuration data for Fastly services
Fastly services execute your edge code, which is compiled into a service version and is immutable once deployed to our edge cloud. However, you may have additional data that you want to make available to the service at runtime, but which isn't hard-coded into the application itself - for example, feature flags, IP ranges, secrets, keys, tokens, URL mappings, user preferences etc.
Dynamic configuration is data that is available to your application at runtime, and editable without creating a new version of your service. All dynamic configuration options shown here are read-only at the edge, writable via the Fastly API, globally consistent, durable, and have low read latency (around 1ms).
HINT: For data storage that is writable at the edge, see Data stores.
The following dynamic configuration features are currently available:
Product | Platforms | Shareable | Typical use cases |
---|---|---|---|
Edge dictionaries | VCL only | No | Configuration |
Access control lists | VCL only | No | IP allowlists / blocklists |
Config stores | Compute only | Yes | Configuration |
Secret stores | Compute only | Yes | Secrets |
Edge dictionaries
Edge dictionaries are small, durable, globally consistent key-value stores for string keys and values, which offer extremely fast read performance (microseconds) at the edge and a separate HTTP API for writes. Dictionaries are ideal for storing configuration such as flags, A/B testing settings, path routing rules, and more. Updates to dictionaries made via the Fastly API are available at the edge within around 30 seconds.
Dictionaries can be created and managed via multiple methods:
Create dictionary | Add/update item | List items | |
---|---|---|---|
Using the fastly CLI | fastly dictionary create | fastly dictionary-item update | fastly dictionary-item list |
Using the API | Create dictionary endpoint | Update item endpoint | List items endpoint |
Using the web interface | See Creating a dictionary | See Creating a dictionary item | See Creating a dictionary |
Dictionaries must be created on a draft version of your service, and once a new dictionary is created, the new version of the service must be activated to make the dictionary available at the edge. The dictionary will then be accessible to your code via the name you assigned it. Using the CLI, you can create a new version of your service and add a dictionary to it in one step:
$ fastly dictionary create --version=active --autoclone --name=ttls$ fastly service-version activate --version=latest
In VCL services, dictionaries are exposed as VCL tables and can be accessed using the table.contains
and table.lookup
functions. In the following example, a dictionary maps URL path prefixes (such as /products
) to an override TTL (the cache lifetime in seconds). When a request is received for a URL matching one of the paths in the dictionary, the override TTL is applied.
Dictionary items are versionless.
Limitations
Edge dictionaries are subject to the following constraints:
- Dictionaries are not writable from edge code.
- Maximum 1000 keys per dictionary. If you need more, contact Fastly support and we can discuss your use case.
- Keys may be up to 256 characters long. Values may be up to 8000 characters long.
- All keys and values are strings. VCL provides other typed tables but these are not manageable as Edge Dictionaries.
- Dictionaries cannot be shared between services.
Private dictionaries
When creating an edge dictionary via the API or fastly dictionary create, the write_only
property may be set to mark the dictionary as private. This will prevent dictionary items being enumerated via the API, and will redact the VCL table
declarations that are generated into VCL services. However, the contents of private edge dictionaries are still stored in plain text and are not recommended for storing secrets, credentials or personal data.
Access control lists
Exclusive to VCL services, ACLs store lists of IP addresses or subnets. These are useful for making access or content decisions based on the identity of the client - perhaps to block malicious clients, provide privileged access to your organization's own IP ranges, or to conduct A/B testing on groups identified by IP.
Using the ~
operator in VCL, you can check whether a given IP address is a member of the ACL. While you can write ACL definitions into VCL source code directly, they can also be created and managed separately, and Fastly will generate the ACL definition for you when your VCL is compiled. Updates to ACLs made via the Fastly API are available at the edge within around 30 seconds.
Similarly to edge dictionaries, ACLs are small, durable, globally consistent, and read-only at runtime. A managed ACL can be created and updated in a number of ways:
Create ACL | Add entry | Update entry | List entries | |
---|---|---|---|---|
Using the fastly CLI | fastly acl create | fastly acl-entry create | fastly acl-entry update | fastly acl-entry list |
Using the API | Create ACL endpoint | Create entry endpoint | Update entry endpoint | List entries endpoint |
Using the web interface | See Creating an ACL | See Creating an ACL entry | See Editing an ACL entry | See Viewing ACLs |
ACLs must be created on a draft version of your service, and once a new ACL is created, the new version of the service must be activated to make the ACL available at the edge. The ACL will then be accessible to your code via the name you assigned it. Using the CLI, you can create a new version of your service and add an ACL to it in one step:
$ fastly acl create --version=active --autoclone --name=ban_acl$ fastly service-version activate --version=latest
To test whether an IP address is in an ACL, use the ~
operator:
Limitations
ACLs are subject to similar constraints to edge dictionaries:
- ACLs are not writable from edge code.
- Maximum 1000 entries per ACL. If you need more, contact Fastly support and we can discuss your use case.
- Entries must be IPv4 or IPv6 addresses or subnets.
- ACLs cannot be shared between services.
- ACLs are not currently available in Compute services.
Config stores
Like dictionaries, Config stores are durable, globally consistent key-value stores for string keys and values, which offer extremely fast read performance (microseconds) at the edge, a separate HTTP API for writes and are designed for configuration data such as flags, A/B testing settings, path routing rules, etc. Config stores differ from edge dictionaries in the following respects:
- Config stores are only available to Compute services, whereas dictionaries are only available in VCL services.
- Config stores are optimized for up to 100,000 entries.
- As a service-linked resource, config stores can be shared between services.
Config stores can be created using the Config store API, and must be attached to a service using the Resources API.
For example, the following curl commands create a config store and add it to a service:
# Create a config store$ curl -i -X POST "https://api.fastly.com/resources/stores/config" -H "Fastly-Key: YOUR_FASTLY_TOKEN" -H "Content-Type: application/json" -H "Accept: application/json" -d '{"name":"example-store"}'
# Link the config store to a service$ curl -i -X POST "https://api.fastly.com/service/YOUR_FASTLY_SERVICE_ID/version/YOUR_FASTLY_SERVICE_VERSION/resource" -H "Fastly-Key: YOUR_FASTLY_TOKEN" -H "Content-Type: application/x-www-form-urlencoded" -H "Accept: application/json" -d "name=example_store_service_a&resource_id=YOUR_CONFIG_STORE_ID"
Config stores are exposed to Compute services via dedicated interfaces in each SDK:
- Rust
- JavaScript
- Go
use fastly::{Error, ConfigStore, Request, Response};
#[fastly::main]fn main(_request: Request) -> Result<Response, Error> {
// Define a config store instance using the resource link name let mut store = ConfigStore::open("example_store_service_a");
// Get the value back from the config store (as a string), // and return it, with HTTP response code 200 let value = store.try_get("cat")?.unwrap_or(""); Ok(Response::from_status(200).with_body(value))}
See the Compute SDKs reference for more information about individual methods in each SDK.
Data in config stores is proactively pushed to all Fastly POPs, and is reliably readable at the edge with sub-millisecond latency.
Limitations and constraints
The following limitations apply:
- Store names have a maximum length of 255 characters, must start with a letter, and may contain only letters, numbers, spaces, and underscores
- Config stores are eventually consistent, so the contents of a given key may not be immediately available to read from all edge locations
- Keys have a maximum length of 1024 UTF-8 characters
- Values have a maximum size of 8000 UTF-8 characters
Secret stores
Secret stores provide a state-of-art solution for encryption and securely storing/retrieving the sensitive information you need to properly operate your Fastly services.
Secret stores can be created and managed via multiple methods:
Create store | Add entry | Delete entry | List entries | |
---|---|---|---|---|
Using the fastly CLI | fastly secret-store create | fastly secret-store-entry create | fastly secret-store-entry delete | fastly secret-store-entry list |
Using the API | Create secret store endpoint | Create secret entry endpoint | Delete secret endpoint | List secrets endpoint |
Secret stores must be attached to a service using the Resources API.
For example, the following curl commands create a secret store and add it to a service:
# Create a secret store$ curl -i -X POST "https://api.fastly.com/resources/stores/secret" -H "Fastly-Key: YOUR_FASTLY_TOKEN" -H "Content-Type: application/json" -H "Accept: application/json" -d '{"name":"example-secrets"}'
# Link the secret store to a service$ curl -i -X POST "https://api.fastly.com/service/YOUR_FASTLY_SERVICE_ID/version/YOUR_FASTLY_SERVICE_VERSION/resource" -H "Fastly-Key: YOUR_FASTLY_TOKEN" -H "Content-Type: application/x-www-form-urlencoded" -H "Accept: application/json" -d "name=example-secrets-service-a&resource_id=YOUR_SECRET_STORE_ID"
Secret stores are exposed to Compute services via dedicated interfaces in each SDK, which return secrets as a complex type with a method that provides access to the plaintext value:
- Rust
- JavaScript
- Go
use fastly::{Error, SecretStore, Request, Response};
#[fastly::main]fn main(_request: Request) -> Result<Response, Error> { let mut secrets = SecretStore::open("example-secrets-service-a")?; let secret = secrets.get("cat-api-key").unwrap(); req.set_header("cat-api-key", secret.plaintext()); let beresp = req.send("example_backend")?; Ok(beresp)}
See the Compute SDKs reference for more information about individual methods in each SDK.
Data in secret stores is proactively pushed to all Fastly POPs, and is reliably readable at the edge with sub-millisecond latency.
Limitations and constraints
The following limitations apply:
- Secret stores are eventually consistent, so a store and its the contents may not be immediately available to read from all edge locations
- Store and secret names have a maximum length of 255 characters and may contain letters, numbers, dashes (-), underscores (_), and periods (.)
- Secret values have a maximum size of 64 kilobytes