SAAS configuration
Evolve manages SAAS service configuration through Terraform, the same infrastructure-as-code tool used for cloud resources. This means commercetools projects, CMS content models, search indices, and observability tools are all defined declaratively, version-controlled, and reproducible across environments.
This approach may be unfamiliar if you’re used to configuring SAAS
services through their web interfaces. The benefit is significant:
spinning up a new environment (staging, demo, new client) is a single
terraform apply that provisions everything, from cloud infrastructure
to SAAS configurations, in one go. No manual clicking through admin
panels, no forgotten settings, no configuration drift between
environments.
What gets configured
Section titled “What gets configured”Evolve includes Terraform configurations for all integrated SAAS services:
Directorybackend/configuration/
Directorycommercetools/ Project settings, stores, channels,
- …
Directory│ product types, tax categories
Directorycontentful/ Locales, content types, editor interfaces
- …
Directorystoryblok/ Components, component groups
- …
Directoryalgolia/ Indices, virtual indices, facet config
- …
Each directory contains a self-contained Terraform module that can be applied independently or orchestrated through MACH Composer.
Commerce configuration
Section titled “Commerce configuration”The commercetools Terraform provider manages the commerce backend: project settings, stores, channels, product types, and tax categories.
resource "commercetools_project_settings" "project" { name = "my-project" countries = ["NL", "DE", "GB"] currencies = ["EUR", "GBP"] languages = ["nl-NL", "en-GB", "de-DE"]
messages { enabled = true }
carts { country_tax_rate_fallback_enabled = true delete_days_after_last_modification = 90 }}
resource "commercetools_store" "primary" { key = "my-store" name = { nl-NL = "My Store" } languages = commercetools_project_settings.project.languages countries = commercetools_project_settings.project.countries
distribution_channels = [ commercetools_channel.store.key ]}Product types, which define the attributes available on products, are also managed through Terraform. This ensures the data model is consistent across environments:
resource "commercetools_product_type" "fashion" { key = "fashion" name = "Fashion" description = "Fashion product type"
attribute { name = "brand" label = { en-GB = "Brand", nl-NL = "Merk" } constraint = "None" type = { name = "text" } searchable = true }}CMS configuration
Section titled “CMS configuration”Both Contentful and Storyblok content models are defined in Terraform. This means the content types and components that content editors work with are version-controlled and consistent across environments.
Contentful
Section titled “Contentful”resource "contentful_contenttype" "hero" { space_id = var.contentful_space_id environment = var.contentful_environment id = "hero" name = "Hero" display_field = "title"
fields = [ { id = "title" name = "Title" type = "Text" }, { id = "image" name = "Image" type = "Link" link_type = "Asset" }, ]}Storyblok
Section titled “Storyblok”resource "storyblok_component" "hero" { name = "hero" space_id = var.storyblok_space_id is_root = false is_nestable = true
schema = { title = { position = 0 translatable = true display_name = "Title" required = true type = "text" } image = { position = 5 translatable = true display_name = "Image" required = true type = "asset" filetypes = ["images"] } }}Search configuration
Section titled “Search configuration”Algolia indices, including facet configuration, searchable attributes, and sort order replicas, are managed through Terraform:
resource "algolia_index" "default" { for_each = local.store_keys name = "${each.value}_default"
attributes_config { searchable_attributes = [ "name", "description", "variants.sku", ] attributes_for_faceting = [ "startingPrice.centAmount", "hierarchicalCategories.lvl0", "variants.attributes.brand", "variants.attributes.color.nl-NL", "variants.attributes.size", ] }}
resource "algolia_virtual_index" "price_asc" { for_each = local.store_keys name = "${each.value}_price_asc" primary_index_name = algolia_index.default[each.key].name
ranking_config { custom_ranking = ["asc(startingPrice.centAmount)"] }}Terraform providers
Section titled “Terraform providers”Evolve uses community-maintained Terraform providers for each SAAS service:
| Service | Provider | Source |
|---|---|---|
| commercetools | labd/commercetools |
Registry |
| Contentful | labd/contentful |
Registry |
| Storyblok | labd/storyblok |
Registry |
| Algolia | k-yomo/algolia |
Registry |
MACH Composer integration
Section titled “MACH Composer integration”MACH Composer ties SAAS configuration into the deployment pipeline. Each SAAS service is registered as a plugin, and components declare which integrations they need:
mach_composer: plugins: commercetools: source: mach-composer/commercetools version: 0.2.1 storyblok: source: mach-composer/storyblok version: 0.0.3 algolia: source: mach-composer/algolia version: 0.1.0 sentry: source: mach-composer/sentry version: 0.1.3SAAS credentials and project-specific settings are defined per environment. MACH Composer injects these as Terraform variables when applying configurations:
sites: - identifier: my-project commercetools: project_key: my-project client_id: ${var.secrets.commercetools.client_id} client_secret: ${var.secrets.commercetools.client_secret} storyblok: space_id: 233248 token: ${var.secrets.storyblok.management_token} algolia: app_id: YWHL59LKQC api_key: ${var.secrets.algolia.write_api_key}Components reference their SAAS integrations, and MACH Composer ensures the right credentials and configurations are passed to each Terraform module:
components: - name: commercetools-config source: ../../backend/configuration/commercetools/ integrations: - commercetools
- name: storyblok-config source: ../../backend/configuration/storyblok/ integrations: - commercetools - storyblok
- name: algolia-config source: ../../backend/configuration/algolia/ integrations: - algoliaThis means adding a new environment is a matter of creating a new MACH Composer configuration file with the right credentials. The Terraform modules handle the rest.

