Multiple Environments

Overview

Sym supports deploying Flows to multiple Environments to separate stable Flows from ones being tested out and iterated on.

Here, we'll take our basic approvals example and refactor it so it can easily be deployed to both a sandbox and main environment.

Create a Module

To make a Sym Flow and related resources reusable, wrap it in a Terraform module. This module can then be called by each of your Environments, so they don't need to define the resources themselves.

There isn't much work to do to turn our existing Approval Flow into a module. First, we need to make sure it's in its own directory. We recommend giving each module a directory inside a main modules directory in your project, so we'll put all the code from the approvals example inside a new directory modules/sym. It should now contain:

  • impl.py
  • main.tf
  • terraform.tfvars
  • variables.tf
  • versions.tf

Then, we'll just make a couple tweaks:

  1. Remove terraform.tfvars. Those values will be passed in from each Environment we set up later.
  2. Remove the provider block. This will also need to be defined in the Environment, since that's where Terraform will actually be applied.
# Remove this!
provider "sym" {
  org = var.sym_org_slug
}

Create Multiple Environments

Now that we have a module, we just need to call it from each of our Environments. Create two new directories: sandbox and main. We recommend putting these in an environments directory as well for organization, so the structure looks like:

- environments
  - sandbox
  - main
- modules
  - sym

Each Environment directory just needs two files: main.tf and versions.tf! versions.tf will contain the exact same thing as the one in the new sym module, so it can just be copied from there. main.tf will set up the Sym provider and invoke our new sym module.

The sandbox Environment will send requests and errors to specific Slack channels, and all the resources will contain "sandbox" in their names.

provider "sym" {
  org = "sym-example"
}

# Create all the necessary resources for an approval flow using a resuable module.
# This one will be a sandbox environment for testing new ideas.
module "sandbox_approval_flow" {
    source = "../../modules/sym"

    # Resources will contain "sandbox" in their name to differentiate environments.
    environment_name = "sandbox"
    error_channel_name = "#sym-sandbox-errors"
    slack_workspace_id = "T123ABC"

    # Configure the sym_flow to send sandbox requests to their own Slack channel.
    flow_variables = {
      request_channel = "#sym-sandbox-requests"      # Slack Channel where requests should go
      approvers       = "[email protected],[email protected]" # Optional safelist of users that can approve requests
    }
}

The main Environment will send requests and errors to their own Slack channels, and all the resources will contain "main" in their names.

provider "sym" {
  org = "sym-example"
}

# Create all the necessary resources for an approval flow using a resuable module.
# This one will be our stable environment for daily use.
module "main_approval_flow" {
    source = "../../modules/sym"

    # Resources will contain "main" in their name to differentiate environments.
    environment_name = "main"
    error_channel_name = "#sym-errors"
    slack_workspace_id = "T123ABC"

    flow_variables = {
      request_channel = "#sym-requests"      # Slack Channel where requests should go
      approvers       = "[email protected],[email protected]" # Optional safelist of users that can approve requests
    }
}

Wrapping Up

Each Environment can now be applied with Terraform separately. If there are other things you want to make configurable, you can do so by adding more variables to the module. Once everything is applied, you can access your sandbox Flow by clicking "Show All Environments" in the Flow selection modal:

645645

🚧

Moving Terraform configuration around may delete and recreate your resources!

If you're reorganizing your existing Sym configuration and don't want any resources to be deleted and recreated, be sure to use Terraform's moved blocks to move existing resources.

Full Example

You can find the complete code for this example in our Multiple Environments Example.