Skip to main content

Module: stack-config

Terraform module that loads and processes an opinionated "stack" configuration from YAML sources using the terraform-provider-utils Terraform provider.

It supports deep-merged variables, settings, ENV variables, backend config, remote state, and Spacelift stacks config outputs for Terraform and helmfile components.

Introduction

The module is composed of the following sub-modules:

  • vars - accepts stack configuration and returns deep-merged variables for a Terraform or helmfile component.
  • settings - accepts stack configuration and returns deep-merged settings for a Terraform or helmfile component.
  • env - accepts stack configuration and returns deep-merged ENV variables for a Terraform or helmfile component.
  • backend - accepts stack configuration and returns backend config for a Terraform component.
  • remote-state - accepts stack configuration and returns remote state outputs for a Terraform component. The module supports s3 and remote (Terraform Cloud) backends.
  • spacelift - accepts infrastructure stack configuration and transforms it into Spacelift stacks.

Usage

For a complete example, see examples/complete.

For automated tests of the complete example using bats and Terratest, see test.

For an example on how to configure remote state for Terraform components in YAML config files and then read the components outputs from the remote state, see examples/remote-state.

For an example on how to process vars, settings, env and backend configurations for all Terraform and helmfile components for a list of stacks, see examples/stacks.

Examples

Here's an example of a stack configuration file:

  import:
- ue2-globals
vars:
stage: dev
terraform:
vars: {}
helmfile:
vars: {}
components:
terraform:
vpc:
backend:
s3:
workspace_key_prefix: "vpc"
vars:
cidr_block: "10.102.0.0/18"
eks:
backend:
s3:
workspace_key_prefix: "eks"
vars: {}
helmfile:
nginx-ingress:
vars:
installed: true

The import section refers to other stack configurations that are automatically deep merged.

Complete example

This example loads the stack config my-stack (which in turn imports other YAML config dependencies) and returns variables and backend config for the Terraform component my-vpc from the stack my-stack.

  module "vars" {
source = "cloudposse/stack-config/yaml//modules/vars"
# version = "x.x.x"

stack_config_local_path = "./stacks"
stack = "my-stack"
component_type = "terraform"
component = "my-vpc"

context = module.this.context
}

module "backend" {
source = "cloudposse/stack-config/yaml//modules/backend"
# version = "x.x.x"

stack_config_local_path = "./stacks"
stack = "my-stack"
component_type = "terraform"
component = "my-vpc"

context = module.this.context
}

module "settings" {
source = "cloudposse/stack-config/yaml//modules/settings"
# version = "x.x.x"

stack_config_local_path = "./stacks"
stack = "my-stack"
component_type = "terraform"
component = "my-vpc"

context = module.this.context
}

module "env" {
source = "cloudposse/stack-config/yaml//modules/env"
# version = "x.x.x"

stack_config_local_path = "./stacks"
stack = "my-stack"
component_type = "terraform"
component = "my-vpc"

context = module.this.context
}

The example returns the following deep-merged vars, settings, env, and backend configurations for the my-vpc Terraform component:

backend = {
"acl" = "bucket-owner-full-control"
"bucket" = "eg-ue2-root-tfstate"
"dynamodb_table" = "eg-ue2-root-tfstate-lock"
"encrypt" = true
"key" = "terraform.tfstate"
"region" = "us-east-2"
"role_arn" = "arn:aws:iam::xxxxxxxxxxxx:role/eg-gbl-root-terraform"
"workspace_key_prefix" = "vpc"
}

backend_type = "s3"
base_component = "vpc"

env = {
"ENV_TEST_1" = "test1_override"
"ENV_TEST_2" = "test2_override"
"ENV_TEST_3" = "test3"
"ENV_TEST_4" = "test4"
}

settings = {
"spacelift" = {
"autodeploy" = true
"branch" = "test"
"triggers" = [
"1",
"2",
]
"workspace_enabled" = true
}
"version" = 1
}

vars = {
"availability_zones" = [
"us-east-2a",
"us-east-2b",
"us-east-2c",
]
"cidr_block" = "10.132.0.0/18"
"environment" = "ue2"
"level" = 3
"namespace" = "eg"
"param" = "param4"
"region" = "us-east-2"
"stage" = "prod"
"subnet_type_tag_key" = "example/subnet/type"
"test_map" = {
"a" = "a_override_2"
"b" = "b_override"
"c" = [
1,
2,
3,
]
"map2" = {
"atr1" = 1
"atr2" = 2
"atr3" = [
"3a",
"3b",
"3c",
]
}
}
"var_1" = "1_override"
"var_2" = "2_override"
"var_3" = "3a"
}

See examples/complete for more details.

Remote state example

This example accepts a stack config my-stack (which in turn imports other YAML config dependencies) and returns remote state outputs from the s3 backend for my-vpc and eks Terraform components.

NOTE: The backend type (s3) and backend configuration for the components are defined in the stack YAML config files.

  module "remote_state_my_vpc" {
source = "cloudposse/stack-config/yaml//modules/remote-state"
# Cloud Posse recommends pinning every module to a specific version
# version = "x.x.x"

stack_config_local_path = "./stacks"
stack = "my-stack"
component = "my-vpc"
}

module "remote_state_eks" {
source = "cloudposse/stack-config/yaml//modules/remote-state"
# Cloud Posse recommends pinning every module to a specific version
# version = "x.x.x"

stack_config_local_path = "./stacks"
stack = "my-stack"
component = "eks"
}

See examples/remote-state for more details.