Skip to content

Overview

A configuration file can contain several sites with all different configurations and all using a different mix of re-usable serverless microservice components.

It is common to have a single configuration file per environment since they usually share the same general configurations.

Schema

The root schema is show below.

$schema: "http://json-schema.org/draft-07/schema#"
description: Main MACH configuration object.
additionalProperties: false
type: object
properties:
  mach_composer:
    $ref: "#/definitions/MachComposerConfig"
  global:
    $ref: "#/definitions/GlobalConfig"
  sites:
    type: array
    items:
      $ref: "#/definitions/SiteConfig"
  components:
    oneOf:
      - type: string
      - type: object
        properties:
          '$ref':
            type: string
      - type: array
        items:
          $ref: "#/definitions/ComponentConfig"

definitions:
  MachComposerConfig:
    type: object
    required:
      - version
    additionalProperties: false
    properties:
      version:
        type:
          - string
          - number
      variables_file:
        type: string
      cloud:
        $ref: "#/definitions/MachComposerCloud"
      deployment:
        $ref: "#/definitions/MachComposerDeployment"
      plugins:
        type: object
        additionalProperties: false
        patternProperties:
          "^[a-zA-Z-]+$":
            type: object
            additionalProperties: false
            properties:
              source:
                type: string
              version:
                type: string
              replace:
                description: |
                  If set, the plugin will be replaced with the one from the
                  local filesystem. This is useful for development purposes.
                type: string

  MachComposerCloud:
    type: object
    required:
      - organization
      - project
    properties:
      organization:
        type: string
      project:
        type: string

  GlobalConfig:
    type: object
    description: Config that is shared across sites.
    additionalProperties: true
    required:
      - environment
      - terraform_config
      - cloud
    properties:
      environment:
        type: string
      terraform_config:
        $ref: "#/definitions/TerraformConfig"
      cloud:
        type: string
      variables:
        $ref: "#/definitions/MachComposerVariables"
        description: Global variables. These will be merged with the site specific variables, where the site variables will take precedence
      secrets:
        $ref: "#/definitions/MachComposerSecrets"
        description: Global secrets. These will be merged with the site specific secrets, where the site secrets will take precedence

  TerraformConfig:
    type: object
    description: Terraform configuration.
    additionalProperties: true
    properties:
      providers:
        type: object
        additionalProperties: false
        patternProperties:
          "^[a-zA-Z-]+$":
            type: string
      remote_state:
        allOf:
          - type: object
            additionalProperties: true
            required:
              - plugin
            properties:
              plugin:
                type: string
                enum:
                  - aws
                  - gcp
                  - azure
                  - terraform_cloud
                  - local
          - $ref: "#/definitions/RemoteState"

  RemoteState:
    type: object
    properties: { }

  SiteConfig:
    type: object
    description: Site definition.
    additionalProperties: true
    required:
      - identifier
    properties:
      identifier:
        type: string
      endpoints:
        type: object
        deprecationMessage: |
          The `endpoints` configuration is deprecated. Please refer to the docs
          on how to change implementation
        patternProperties:
          "^[A-Za-z0-9+-]+$":
            oneOf:
              - type: string
              - $ref: "#/definitions/SiteEndpointConfig"
      deployment:
        $ref: "#/definitions/MachComposerDeployment"
      variables:
        $ref: "#/definitions/MachComposerVariables"
        description: Site specific variables. These will be merged with the component variables, where the component variables will take precedence
      secrets:
        $ref: "#/definitions/MachComposerSecrets"
        description: Site specific secrets. These will be merged with the component secrets, where the component secrets will take precedence
      components:
        type: array
        items:
          $ref: "#/definitions/SiteComponentConfig"

  SiteEndpointConfig:
    type: object
    additionalProperties: true
    properties:
      url:
        type: string
      key:
        type: string
      zone:
        type: string

  SiteComponentConfig:
    type: object
    description: Component configuration.
    additionalProperties: true
    required:
      - name
    properties:
      name:
        type: string
      variables:
        $ref: "#/definitions/MachComposerVariables"
      secrets:
        $ref: "#/definitions/MachComposerSecrets"
      store_variables:
        description: Commercetools store specific variables
        deprecationMessage: The `store_variables` configuration is deprecated
        type: object
      store_secrets:
        description: Commercetools store specific variables
        deprecationMessage: The `store_secrets` configuration is deprecated
        type: object
      health_check_path:
        type: string
        deprecationMessage: The `health_check_path` configuration is deprecated
      deployment:
        $ref: "#/definitions/MachComposerDeployment"
      depends_on:
        description: |
          List of components that this component depends on. This will override 
          any implicit links based on variables
        type: array
        items:
          type: string

  ComponentConfig:
    type: object
    additionalProperties: true
    required:
      - name
      - source
      - version
    properties:
      name:
        type: string
      source:
        type: string
      paths:
        type: array
        items:
          type: string
      version:
        type: string
      integrations:
        type: array
        items:
          type: string
      endpoints:
        $ref: "#/definitions/ComponentEndpointConfig"
      health_check_path:
        type: string
      branch:
        type: string
    description: Component definition.

  ComponentEndpointConfig:
    type: object
    deprecationMessage: |
      The `endpoints` configuration is deprecated. Please refer to the 
      docs on how to change implementation
    additionalProperties: false
    patternProperties:
      "[a-zA-Z0-9]+":
        type: string

  MachComposerVariables:
    description: |
      Variables are used to configure the components. They are passed to the terraform module as a terraform 
      variable with the name `variables` containing an object with the same fields:

      ```yaml
      components:
      - name: my-component
        variables:
          my_string_field: "my string value"
          my_number_field: 42
      ```

      ```
      variable "variables" {
        type = object({
          my_string_field = string
          my_number_field = number
        })
      }
      ```
    type: object

  MachComposerSecrets:
    description: |
      Secrets are used to configure the components. They are passed to the terraform module as a terraform 
      variable with the name `secrets` containing an object with the same fields:

      ```yaml
      components:
      - name: my-component
        secrets:
          my_string_field: "my string value"
          my_number_field: 42
      ```

      ```
      variable "secrets" {
        type = object({
          my_string_field = string
          my_number_field = number
        })
      }
      ```
    type: object

  MachComposerDeployment:
    type: object
    description: |
      The deployment configuration determines the way a component is deployed. The following forms are supported:
      - site: deploy site-based; this means all components will be deployed as part of a single terraform file
      - site-component: deploy site-component based; this means each site component will be deployed as a separate terraform 
      file

      These configurations can be set both at the root level and per site component. The combination of root site with 
      specific site components is also supported (this will deploy all site components as part of a single terraform file,
      excepting the ones that have a specific deployment configuration). The other way around is not supported.

      The default is site.
    properties:
      type:
        type: string
        enum:
          - site
          - site-component
        description: "Determines how the state will be split. Defaults to site"
        default: "site"

This can however be extended through the use of plugins, which declare their own bits of configuration. For development purposes it is possible to generate a JSON schema for the required configuration. This can be used to configure autocompletion and syntax checking support in your favorite IDE.

To generate the schema, run the following command:

mach-composer schema

See the CLI documentation for more information.

Required

General syntax

The configuration syntax follows the same basic rules as YAML, with some extra features.

Plugins extending functionality

Plugins can be used to extend the functionality of mach-composer. They can be added to the configuration file using the plugins key in the mach_composer configuration.

In essence a plugin will add additional terraform code to your module where appropriate. These additional elements might add additional configuration options on a global, site and site-component level which can change behaviour. See the documentation of the plugin for more information on what plugins are available, what they do and what to add where.

Including YAML files

Using the $ref syntax it is possible to load in other yaml files as part of your configuration.

This can be used for example to manage your component definitions elsewhere within the same directory like so;

---
mach_composer: ...
global: ...
sites: ...
components:
  $ref: _components.yaml

Variables

MACH composer support the usage of variables in a configuration file. This is a good way to keep your configuration DRY and to keep sensitive information separate.

The following types are supported;

Example

mach_composer:
  version: 1
global:
  environment: ${env.MACH_ENVIRONMENT}
  cloud: aws
sites:
  - identifier: my-site
    aws:
      account_id: 1234567890
      region: eu-central-1
    endpoints:
      public: api.tst.mach-example.net
    components:
      - name: infra
      - name: payment
        variables:
          sns_topic: ${components.infra.sns_topic_arn}
        secrets:
          stripe_secret_key: ${var.stripe_secret}
  • ${components.infra.sns_topic_arn} uses the sns_topic_arn Terraform output as a value for the payment component
  • ${var.stripe_secret} reads the stripe_secret from a variables file
  • ${env.MACH_ENVIRONMENT} reads the MACH_ENVIRONMENT environment variable

component

Usage ${component.<component-name>.<output-value>}

You can use this to refer to any Terraform output that another component has defined.

So for example if a component called "email" has the following outputs:

# outputs.tf

output "sqs_queue" {
  value = {
    id  = aws_sqs_queue.email_queue.id
    arn = aws_sqs_queue.email_queue.arn
  }
}

These can then be used in the configuration:

components:
  - name: order-notifier
    variables:
      email_queue_id: ${component.email.sqs_queue.id}

var

Usage ${var.<variable-key>}

This can be used for using values from a variables file. This variable file must be set by using the --var-file CLI option:

mach-composer apply -f main.yml --var-file variables.yml

From the example above, the following configuration line:

stripe_secret_key: ${var.stripe_secret}

will use the stripe_secret value from the given variables file.

These values can be nested, so it's possible to define a ${var.site1.stripe.secret_key} with your variables.yml looking like:

    ```yaml
    ---
    site1:
      stripe:
        secret_key: vRBNcBH2XuNvHwAoPdDnhs2XyeVMOT
    site2:
      stripe:
        secret_key: 2hzctJCLjyMjUL07BNSh3Nyjt6r7aC
```

Note on encryption

You can encrypt your variables.yml using SOPS.

When doing so, MACH composer won't render the variable files directly into your Terraform configuration but uses terraform-sops to refer you the SOPS encrypted variables within the Terraform file.

env

Usage ${env.<variable-name>}

Use environment variables in your MACH configuration:

export MACH_ENVIRONMENT=test
mach-composer apply

Will replace ${env.MACH_ENVIRONMENT} in our example with test.

Examples

For examples see the examples directory in the tutorial section.