> ## Documentation Index
> Fetch the complete documentation index at: https://cdktn.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Stacks - CDK Terrain

> Use stacks to specify separate collections of infrastructure for different environments, like test and production.

A stack represents a collection of infrastructure that CDK Terrain (CDKTN) synthesizes as a dedicated Terraform configuration. Stacks allow you to separate the state management for multiple environments within an application.

<Note>Stacks in CDKTN are different from the Terraform stacks concept announced at HashiConf 2023. Terraform stacks are a configuration layer that simplifies provisioning and managing resources at scale by controlling cross-configuration dependencies between Terraform modules. Refer to [Terraform stacks, explained](https://www.hashicorp.com/blog/terraform-stacks-explained) in the HashiCorp blog for additional information.</Note>
<Tip>Try the [Deploy Applications with CDK Terrain](/tutorials/deploy-applications) tutorial.</Tip>

## Scope

You can instantiate the same resource multiple times throughout your infrastructure. For example, you may want to create multiple S3 Buckets with different configurations. Instances that share the same `stack` parent element are considered to be part of the same scope. You must set a different `name` property for each instance to avoid naming conflicts.

Refer to the [constructs documentation](/concepts/constructs#scope) for more details and an example.

## Single Stack

The following example generates a single Terraform configuration in the configured output folder. When you run `cdktn synth`, the synthesized Terraform configuration will be in the folder `cdktf.out/stacks/a-single-stack`

<CodeGroup>
  ```ts TypeScript theme={null}
  import { Construct } from "constructs";
  import { App, TerraformStack } from "cdktn";
  import { AwsProvider } from "@cdktn/provider-aws/lib/aws-provider";
  import { Instance } from "@cdktn/provider-aws/lib/instance";

  class MySingleStack extends TerraformStack {
    constructor(scope: Construct, id: string) {
      super(scope, id);

      new AwsProvider(this, "aws", {
        region: "us-east-1",
      });

      new Instance(this, "Hello", {
        ami: "ami-2757f631",
        instanceType: "t2.micro",
      });
    }
  }

  const singleStackApp = new App();
  new MySingleStack(singleStackApp, "a-single-stack");
  singleStackApp.synth();
  ```

  ```java Java theme={null}
  import software.constructs.Construct;
  import io.cdktn.cdktn.App;
  import io.cdktn.cdktn.TerraformStack;
  import imports.aws.provider.AwsProvider;
  import imports.aws.provider.AwsProviderConfig;
  import imports.aws.instance.Instance;
  import imports.aws.instance.InstanceConfig;

  public class MainSingleStack extends TerraformStack {

      public MainSingleStack(Construct scope, String id) {
          super(scope, id);

          new AwsProvider(this, "aws", AwsProviderConfig.builder()
                  .region("us-east-1")
                  .build());

          new Instance(this, "Hello", InstanceConfig.builder()
                  .ami("ami-2757f631")
                  .instanceType("t2.micro")
                  .build());
      }

      public static void main(String[] args) {
          final App app = new App();
          new MainSingleStack(app, "a-single-stack");
          app.synth();
      }
  }
  ```

  ```python Python theme={null}
  from constructs import Construct
  from cdktn import App, TerraformStack
  from imports.aws.instance import Instance
  from imports.aws.provider import AwsProvider

  class MySingleStack(TerraformStack):
      def __init__(self, scope: Construct, id: str):
          super().__init__(scope, id)

          AwsProvider(self, "aws",
              region = "us-east-1"
          )

          Instance(self, "Hello",
              ami = "ami-2757f631",
              instance_type = "t2.micro"
          )

  app = App()
  MySingleStack(app, "a-single-stack")
  app.synth
  ```

  ```csharp C# theme={null}
      class MySingleStack : TerraformStack
      {
          public MySingleStack(Construct scope, string name) : base(scope, name)
          {

              new AwsProvider(this, "aws", new AwsProviderConfig
              {
                  Region = "eu-central-1"
              });

              new Instance(this, "instance", new InstanceConfig
              {
                  Ami = "ami-2757f631",
                  InstanceType = "t2.micro",
              });
          }
          public static void Main(string[] args)
          {
              App app = new App();
              new MySingleStack(app, "a-single-stack");

              app.Synth();
              Console.WriteLine("App synth complete");
          }
      }
  ```

  ```go Go theme={null}

  import (
  	"github.com/aws/constructs-go/constructs/v10"
  	"github.com/aws/jsii-runtime-go"
  	"github.com/open-constructs/cdk-terrain-go/cdktn"
  	"github.com/open-constructs/cdk-terrain/examples/go/documentation/generated/hashicorp/aws/instance"
  	aws "github.com/open-constructs/cdk-terrain/examples/go/documentation/generated/hashicorp/aws/provider"
  )

  func NewSingleStack(scope constructs.Construct, name string) cdktn.TerraformStack {
  	stack := cdktn.NewTerraformStack(scope, &name)

  	aws.NewAwsProvider(stack, jsii.String("aws"), &aws.AwsProviderConfig{
  		Region: jsii.String("us-east-1"),
  	})

  	instance.NewInstance(stack, jsii.String("Hello"), &instance.InstanceConfig{
  		Ami:          jsii.String("ami-2757f631"),
  		InstanceType: jsii.String("t2.micro"),
  	})

  	return stack
  }

  func main() {
  	app := cdktn.NewApp(nil)

  	stack := NewSingleStack(app, "a-single-stack")


  	app.Synth()
  }

  ```
</CodeGroup>

## Multiple Stacks

<Tip>Try the [Deploy Multiple Lambda Functions with TypeScript](/tutorials/lambda-functions) tutorial. This tutorial guides you through a multi-stack application.</Tip>

You can specify multiple stacks in your application. For example, you may want a separate configuration for development, testing, and production environments.

The following example synthesizes multiple Terraform configurations in the configured output folder.

<CodeGroup>
  ```ts TypeScript theme={null}
  import { Construct } from "constructs";
  import { App, TerraformStack } from "cdktn";
  import { AwsProvider } from "@cdktn/provider-aws/lib/aws-provider";
  import { Instance } from "@cdktn/provider-aws/lib/instance";

  interface MyMultiStackConfig {
    environment: string;
    region?: string;
  }

  class MyMultiStack extends TerraformStack {
    constructor(scope: Construct, id: string, config: MyMultiStackConfig) {
      super(scope, id);

      const { region = "us-east-1" } = config;

      new AwsProvider(this, "aws", {
        region,
      });

      new Instance(this, "Hello", {
        ami: "ami-2757f631",
        instanceType: "t2.micro",
        tags: {
          environment: config.environment,
        },
      });
    }
  }

  const multiStackApp = new App();
  new MyMultiStack(multiStackApp, "multiple-stacks-dev", {
    environment: "dev",
  });
  new MyMultiStack(multiStackApp, "multiple-stacks-staging", {
    environment: "staging",
  });
  new MyMultiStack(multiStackApp, "multiple-stacks-production-us", {
    environment: "production",
    region: "us-east-1",
  });
  new MyMultiStack(multiStackApp, "multiple-stacks-production-eu", {
    environment: "production",
    region: "eu-central-1",
  });
  multiStackApp.synth();
  ```

  ```java Java theme={null}
  import software.constructs.Construct;
  import io.cdktn.cdktn.App;
  import io.cdktn.cdktn.TerraformStack;
  import imports.aws.instance.Instance;
  import imports.aws.instance.InstanceConfig;
  import imports.aws.provider.AwsProvider;
  import imports.aws.provider.AwsProviderConfig;

  public class MainMultipleStacks extends TerraformStack {

      public MainMultipleStacks(Construct scope, String id, MultipleStacksConfig config) {
          super(scope, id);

          String region = config.region != null ? config.region : "us-east-1";

          new AwsProvider(this, "aws", AwsProviderConfig.builder()
                  .region(region)
                  .build());

          new Instance(this, "Hello", InstanceConfig.builder()
                  .ami("ami-2757f631")
                  .instanceType("t2.micro")
                  .tags(new HashMap<String, String>() {
                      {
                          put("environment", config.myEnvironment);
                      }
                  })
                  .build());
      }

      public static class MultipleStacksConfig {

          public String myEnvironment;
          public String region;

          public MultipleStacksConfig setEnvironment(String environment) {
              Objects.requireNonNull(environment, "environment must be non-null");
              this.myEnvironment = environment;
              return this;
          }

          public MultipleStacksConfig setRegion(String region) {
              this.region = region;
              return this;
          }
      }

      public static void main(String[] args) {
          final App app = new App();
          new MainMultipleStacks(app, "multiple-stacks-dev",
                  new MainMultipleStacks.MultipleStacksConfig().setEnvironment("dev"));
          new MainMultipleStacks(app, "multiple-stacks-staging",
                  new MainMultipleStacks.MultipleStacksConfig().setEnvironment("staging"));
          new MainMultipleStacks(app, "multiple-stacks-production-us",
                  new MainMultipleStacks.MultipleStacksConfig().setEnvironment("staging").setRegion("eu-central-1"));

          app.synth();
      }
  }
  ```

  ```python Python theme={null}
  from constructs import Construct
  from cdktn import App, TerraformStack
  from imports.aws.instance import Instance
  from imports.aws.provider import AwsProvider

  class MyMultipleStacksConfig:
      environment: str
      region: str = None
      def __init__(self, environment: str, region: str = None):
          self.environment = environment
          self.region = region


  class MyMultipleStacks(TerraformStack):
      def __init__(self, scope: Construct, id: str, config: MyMultipleStacksConfig):
          super().__init__(scope, id)

          region = "us-east-1" if config.region == None else config.region

          AwsProvider(self, "aws",
              region = region
          )

          Instance(self, "Hello",
              ami = "ami-2757f631",
              instance_type = "t2.micro",
              tags = {
                  "environment": config.environment,
              }
          )

  multi_stack_app = App()
  MyMultipleStacks(multi_stack_app, "multiple-stacks-dev", MyMultipleStacksConfig(environment = "dev"))
  MyMultipleStacks(multi_stack_app, "multiple-stacks-staging", MyMultipleStacksConfig(environment = "staging"))
  MyMultipleStacks(multi_stack_app, "multiple-stacks-production-us", MyMultipleStacksConfig(environment = "staging", region = "eu-central-1"))

  multi_stack_app.synth
  ```

  ```csharp C# theme={null}
      public interface IMyMultiStackConfig
      {
          string Environment { get; set; }
          string Region { get; set; }
      }

      public class MyMultiStackConfig : IMyMultiStackConfig
      {
          public string Environment { get; set; }
          public string Region { get; set; } = "us-east-1";
      }

      class MyMultiStack : TerraformStack
      {
          public MyMultiStack(Construct scope, string name, IMyMultiStackConfig config) : base(scope, name)
          {

              new AwsProvider(this, "aws", new AwsProviderConfig
              {
                  Region = config.Region,
              });

              new Instance(this, "instance", new InstanceConfig
              {
                  Ami = "ami-2757f631",
                  InstanceType = "t2.micro",
                  Tags = new Dictionary<string, string> {
                      { "environment", config.Environment }
                  }
              });
          }
          public static void Main(string[] args)
          {
              App app = new App();
              new MyMultiStack(app, "multiple-stacks-dev", new MyMultiStackConfig {
                  Environment = "dev",
              });
              new MyMultiStack(app, "multiple-stacks-staging", new MyMultiStackConfig {
                  Environment = "staging",
              });

              new MyMultiStack(app, "multiple-stacks-production-us", new MyMultiStackConfig {
                  Environment = "production",
                  Region = "us-east-1",
              });

              new MyMultiStack(app, "multiple-stacks-production-eu", new MyMultiStackConfig {
                  Environment = "production",
                  Region = "eu-central-1",
              });

              app.Synth();
              Console.WriteLine("App synth complete");
          }
      }
  ```

  ```go Go theme={null}

  import (
  	"github.com/aws/constructs-go/constructs/v10"
  	"github.com/aws/jsii-runtime-go"
  	"github.com/open-constructs/cdk-terrain-go/cdktn"
  	"github.com/open-constructs/cdk-terrain/examples/go/documentation/generated/hashicorp/aws/instance"
  	aws "github.com/open-constructs/cdk-terrain/examples/go/documentation/generated/hashicorp/aws/provider"
  )

  type MultiStackConfig struct {
  	Environment string
  	Region      *string
  }

  func NewMultiStack(scope constructs.Construct, name string, config MultiStackConfig) cdktn.TerraformStack {
  	stack := cdktn.NewTerraformStack(scope, &name)

  	region := config.Region
  	if region == nil {
  		region = jsii.String("us-east-1")
  	}

  	aws.NewAwsProvider(stack, jsii.String("aws"), &aws.AwsProviderConfig{
  		Region: region,
  	})

  	instance.NewInstance(stack, jsii.String("Hello"), &instance.InstanceConfig{
  		Ami:          jsii.String("ami-2757f631"),
  		InstanceType: jsii.String("t2.micro"),
  		Tags: &map[string]*string{
  			"environment": &config.Environment,
  		},
  	})

  	return stack
  }

  func main() {
  	app := cdktn.NewApp(nil)

  	NewMultiStack(app, "multiple-stacks-dev", MultiStackConfig{
  		Environment: "dev",
  	})
  	NewMultiStack(app, "multiple-stacks-staging", MultiStackConfig{
  		Environment: "staging",
  	})
  	NewMultiStack(app, "multiple-stacks-production-us", MultiStackConfig{
  		Environment: "production",
  		Region:      jsii.String("us-east-1"),
  	})
  	NewMultiStack(app, "multiple-stacks-production-eu", MultiStackConfig{
  		Environment: "production",
  		Region:      jsii.String("eu-central-1"),
  	})

  	app.Synth()
  }

  ```
</CodeGroup>

Running `cdktn synth` produces the following synthesized stacks.

```
$ cdktn list

Stack name                      Path
multiple-stacks-dev             cdktf.out/stacks/multiple-stacks-dev
multiple-stacks-staging         cdktf.out/stacks/multiple-stacks-staging
multiple-stacks-production-us   cdktf.out/stacks/multiple-stacks-production-us
multiple-stacks-production-eu   cdktf.out/stacks/multiple-stacks-production-eu
```

To deploy and destroy multiple stacks at once, either specify multiple stacks in the `cdktn deploy` and `cdktn destroy` command or use a wild card glob (e.g., `cdktn deploy '*-production'`).

Refer to [Best Practices](/create-and-deploy/best-practices#separate-business-units-with-stacks) for more details about when to create multiple stacks and how to structure them.

### Cross-Stack References

When you reference resources from one stack in another stack, you can do so by exposing the resource in the source stack and referencing it in the target stack.

<CodeGroup>
  ```ts TypeScript theme={null}
  import { Construct } from "constructs";
  import { App, TerraformStack } from "cdktn";
  import { AwsProvider } from "@cdktn/provider-aws/lib/aws-provider";
  import { Instance } from "@cdktn/provider-aws/lib/instance";
  import { Vpc } from "./constructs/vpc";
  import { DockerBackend } from "./constructs/docker-backend";

  class VPCStack extends TerraformStack {
    public vpc: Vpc;
    constructor(
      scope: Construct,
      id: string,
      public region = "us-east-1",
    ) {
      super(scope, id);

      new AwsProvider(this, "aws", {
        region,
      });

      this.vpc = new Vpc(this, "vpc", {});
    }
  }

  interface BackendStackConfig {
    region: string;
    vpcId: string;
    dockerImage: string;
  }

  class BackendStack extends TerraformStack {
    constructor(scope: Construct, id: string, config: BackendStackConfig) {
      super(scope, id);

      const { region, vpcId, dockerImage } = config;

      new AwsProvider(this, "aws", {
        region,
      });

      new DockerBackend(this, "docker-backend", {
        vpcId,
        dockerImage,
      });
    }
  }

  const crossStackReferenceApp = new App();
  const origin = new VPCStack(crossStackReferenceApp, "origin-stack");
  new BackendStack(crossStackReferenceApp, "target-stack", {
    region: origin.region,
    vpcId: origin.vpc.id,
    dockerImage: "org/my-image:latest",
  });

  crossStackReferenceApp.synth();
  ```

  ```java Java theme={null}
  import software.constructs.Construct;
  import io.cdktn.cdktn.App;
  import io.cdktn.cdktn.TerraformStack;
  import imports.aws.provider.AwsProvider;
  import imports.aws.provider.AwsProviderConfig;
  import com.mycompany.app.myconstructs.DockerBackend;
  import com.mycompany.app.myconstructs.DockerBackendConfig;
  import com.mycompany.app.myconstructs.Vpc;

  public class MainCrossStackReferences extends TerraformStack {

      public MainCrossStackReferences(Construct scope, String id){
          super(scope, id);
      }

      public static class VPCStack extends TerraformStack{
          public Vpc vpc;
          public String region = "us-east-1";
          public VPCStack(Construct scope, String id){
              super(scope, id);

              new AwsProvider(this, "aws", AwsProviderConfig.builder()
                      .region(this.region)
                      .build()
              );

              this.vpc = new Vpc(this, "vpc");
          }
      }

      public static class BackendStackConfig{

          public String region;
          public String vpcId;
          public String dockerImage;

          public BackendStackConfig setRegion(String region){
              this.region = region;
              return this;
          }

          public BackendStackConfig setVpcId(String vpcId){
              this.vpcId = vpcId;
              return this;
          }

          public BackendStackConfig setDockerImage(String dockerImage){
              this.dockerImage = dockerImage;
              return this;
          }
      }

      public static class BackendStack extends TerraformStack{

          public BackendStack(Construct scope, String id, BackendStackConfig config){
              super(scope, id);

              new AwsProvider(this, "aws", AwsProviderConfig.builder()
                      .region(config.region)
                      .build()
              );

              new DockerBackend(this, "docker-backend", DockerBackendConfig.builder()
                      .vpcId(config.vpcId)
                      .dockerImage(config.dockerImage)
                      .build()
              );
          }
      }
      public static void main(String[] args) {
          final App app = new App();
          VPCStack origin = new VPCStack(app, "origin-stack");
          new BackendStack(app, "target-stack", new BackendStackConfig()
                  .setRegion(origin.region)
                  .setVpcId(origin.vpc.getId())
                  .setDockerImage("org/my-image:latest")
          );
          app.synth();
      }
  }
  ```

  ```python Python theme={null}
  from constructs import Construct
  from cdktn import App, TerraformStack, Token
  from imports.aws.instance import Instance
  from imports.aws.provider import AwsProvider
  from imports.vpc import Vpc
  from my_constructs import DockerBackend

  class VPCStack(TerraformStack):
      vpc: Vpc
      region = "us-east-1"
      def __init__(self, scope: Construct, id: str):
          super().__init__(scope, id)

          AwsProvider(self, "aws",
              region = self.region
          )

          self.vpc = Vpc(self, "vpc")

  class BackendStackConfig:
      region: str
      vpc_id: str
      docker_image: str
      def __init__(self, region: str, vpc_id: str, docker_image: str):
          self.region = region
          self.vpc_id = vpc_id
          self.docker_image = docker_image

  class BackendStack(TerraformStack):
      def __init__(self, scope: Construct, id: str, config: BackendStackConfig):
          super().__init__(scope, id)

          AwsProvider(self, "aws",
              region = config.region
          )

          DockerBackend(self, "docker-backend",
              vpc_id = config.vpc_id,
              docker_image = config.docker_image
          )

  cross_stack_app = App()
  origin = VPCStack(cross_stack_app, "origin-stack")
  BackendStack(cross_stack_app, "target-stack",
      BackendStackConfig(
          region = origin.region,
          vpc_id = origin.vpc.vpc_id_output,
          docker_image = "org/my-image:latest"
      )
  )

  cross_stack_app.synth()
  ```

  ```csharp C# theme={null}

      public interface IVpcStackConfig
      {
          string Region { get; set; }
      }

      public class VpcStackConfig : IVpcStackConfig
      {
          public string Region { get; set; } = "us-east-1";
      }

      class VpcStack : TerraformStack
      {
          public VpcStack(Construct scope, string name, IVpcStackConfig config) : base(scope, name)
          {

              new AwsProvider(this, "aws", new AwsProviderConfig
              {
                  Region = config.Region,
              });

              Vpc = new MyVpc(this, "vpc", new Dictionary<string, string> { });
          }

          public MyVpc Vpc { get; }
      }

      public interface IBackendStackConfig
      {
          string DockerImage { get; set; }
          string Region { get; set; }
          string VpcId { get; set; }
      }

      public class BackendStackConfig : IBackendStackConfig
      {
          public string DockerImage { get; set; }
          public string Region { get; set; } = "us-east-1";
          public string VpcId { get; set; }
      }

      class BackendStack : TerraformStack
      {
          public BackendStack(Construct scope, string name, IBackendStackConfig config) : base(scope, name)
          {

              new AwsProvider(this, "aws", new AwsProviderConfig
              {
                  Region = config.Region,
              });

              new DockerBackend(this, "docker-backend", new Dictionary<string, string> {
                  { "vpc_id", config.VpcId },
                  { "docker_image", config.DockerImage },
              });
          }
          public static void Main(string[] args)
          {
              App app = new App();

              VpcStack origin = new VpcStack(app, "origin-stack", new VpcStackConfig {
                  Region = "us-east-1",
              });
              new BackendStack(app, "target-stack", new BackendStackConfig {
                  Region = origin.Region,
                  VpcId = origin.Id,
                  DockerImage = "org/my-image:latest",
              });

              app.Synth();
              Console.WriteLine("App synth complete");
          }
      }
  ```

  ```go Go theme={null}

  import (
  	"github.com/aws/constructs-go/constructs/v10"
  	"github.com/aws/jsii-runtime-go"
  	"github.com/open-constructs/cdk-terrain-go/cdktn"
  	aws "github.com/open-constructs/cdk-terrain/examples/go/documentation/generated/hashicorp/aws/provider"
  	"github.com/open-constructs/cdk-terrain/examples/go/documentation/myconstructs"
  )

  type VPCStack struct {
  	Region *string
  	VPC    *myconstructs.VPC
  }

  func NewVPCStack(scope constructs.Construct, name string, region *string) *VPCStack {
  	stack := cdktn.NewTerraformStack(scope, &name)

  	if region == nil {
  		region = jsii.String("us-east-1")
  	}

  	aws.NewAwsProvider(stack, jsii.String("aws"), &aws.AwsProviderConfig{
  		Region: region,
  	})

  	vpc := myconstructs.NewVPC(stack, *jsii.String("vpc"))

  	return &VPCStack{
  		VPC:    vpc,
  		Region: region,
  	}
  }

  type BackendStackConfig struct {
  	Region      string
  	VPCId       string
  	DockerImage string
  }

  func NewBackendStack(scope constructs.Construct, name string, config BackendStackConfig) cdktn.TerraformStack {
  	stack := cdktn.NewTerraformStack(scope, &name)

  	aws.NewAwsProvider(stack, jsii.String("aws"), &aws.AwsProviderConfig{
  		Region: &config.Region,
  	})

  	myconstructs.NewDockerBackend(stack, *jsii.String("docker-backend"), myconstructs.DockerBackendConfig{
  		VPCId:       config.VPCId,
  		DockerImage: config.DockerImage,
  	})

  	return stack
  }

  func main() {
  	app := cdktn.NewApp(nil)

  	origin := NewVPCStack(app, "origin-stack", nil)
  	NewBackendStack(app, "target-stack", BackendStackConfig{
  		Region:      *origin.Region,
  		VPCId:       origin.VPC.Id,
  		DockerImage: "org/my-image:latest",
  	})

  	app.Synth()
  }

  ```
</CodeGroup>

From a usage perspective it looks like we are accessing the `id` value of `vpc` from the `origin-stack` instance of `VpcStack` and then referencing it in the `target-stack` instance of `BackendStack`.
Accessing a value from a different stack causes the value to be exported as `TerraformOutput` in the origin stack.
The value is then accessed through a `TerraformRemoteState` in the target stack.
Both are automatically added to the respective stacks to make the process seemless.

When you are using HCP Terraform, each stack must be its own workspace.
This means that you need to create a separate workspace for each stack and you need to [set the permissions to allow access between the stacks](/terraform/cloud-docs/workspaces/state#remote-state-access-controls).

### Stack Dependencies

We add the stack dependencies in the `cdktf.out/manifest.json` file for each stack under `dependencies`.
By default a stack is dependant on another stack when the data used origins in that stack.
If you e.g. write `this.allResources = Fn.concat([resourceFromStackA.items, resourceFromStackB.items])` in Stack C and use `stackC.allResources` in Stack D, Stack D will be dependant on Stack A and B, but not C since that is not the origin of the data.

To make the dependency explicit, run`stackD.addDependency(stackC)`.

If you want to keep the result of the function attached to one stack and save its state, create a [Terraform Local value](/concepts/variables-and-outputs#local-values) and expose it. The following example creates a `TerraformLocal`.

<CodeGroup>
  ```ts TypeScript theme={null}
  this.allResources = new TerraformLocal(this, "merged_items", [
    sourceStackA.instance.id,
    sourceStackB.instance.id,
  ]);
  ```

  ```java Java theme={null}
  this.allResources = new TerraformLocal(this, "merge_items",
          Fn.concat(Arrays.asList(resourceFromStackA.items, resourceFromStackB.items)));
  ```

  ```python Python theme={null}
  self.allResources =  TerraformLocal(self, "merge_items", Fn.concat([resources_from_stack_a, resources_from_stack_b]))
  ```

  ```csharp C# theme={null}
  this.allResources = new TerraformLocal(this, "merge_items",
          Fn.Concat(new object[]{resourcesFromStackA, resourcesFromStackB}));
  ```

  ```go Go theme={null}

  import (
  	"github.com/aws/constructs-go/constructs/v10"
  	"github.com/aws/jsii-runtime-go"
  	"github.com/open-constructs/cdk-terrain-go/cdktn"
  	"github.com/open-constructs/cdk-terrain/examples/go/documentation/generated/hashicorp/aws/instance"
  	aws "github.com/open-constructs/cdk-terrain/examples/go/documentation/generated/hashicorp/aws/provider"
  )

  type SourceStack struct {
  	Instance instance.Instance
  }

  func NewSourceStack(scope constructs.Construct, name string) SourceStack {
  	stack := cdktn.NewTerraformStack(scope, &name)

  	aws.NewAwsProvider(stack, jsii.String("aws"), &aws.AwsProviderConfig{
  		Region: jsii.String("us-east-1"),
  	})

  	instance := instance.NewInstance(stack, jsii.String("Hello"), &instance.InstanceConfig{
  		Ami:          jsii.String("ami-abcde123"),
  		InstanceType: jsii.String("t2.micro"),
  	})

  	return SourceStack{
  		Instance: instance,
  	}
  }

  type DependencyStack struct {
  	AllResources *[]*string
  }

  func NewDependencyStack(scope constructs.Construct, name string, dependencies []*SourceStack) DependencyStack {
  	stack := cdktn.NewTerraformStack(scope, &name)

  	ids := make([]*string, 0)
  	for _, dep := range dependencies {
  		ids = append(ids, dep.Instance.Id())
  	}

  	allResources := cdktn.NewTerraformLocal(stack, jsii.String("merged_items"), ids)

  	return DependencyStack{
  		AllResources: allResources.AsList(),
  	}
  }

  func NewNestedDependencyStack(scope constructs.Construct, name string, allResources []*string) cdktn.TerraformStack {
  	stack := cdktn.NewTerraformStack(scope, &name)

  	cdktn.NewTerraformOutput(stack, jsii.String("all_resources"), &cdktn.TerraformOutputConfig{
  		Value: allResources,
  	})

  	return stack
  }

  func main() {
  	app := cdktn.NewApp(nil)

  	stackA := NewSourceStack(app, "stack-a")
  	stackB := NewSourceStack(app, "stack-b")

  	stackC := NewDependencyStack(app, "stack-c", []*SourceStack{&stackA, &stackB})

  	NewNestedDependencyStack(app, "stack-d", *stackC.AllResources)

  	app.Synth()
  }

  ```
</CodeGroup>

The CLI will error if you deploy your application without first deploying the dependencies. It will also error if you try to destroy infrastructure without destroying the dependent stacks first. To remove these safeguards, add the `--ignore-missing-stack-dependencies` to the `deploy` and `destroy` commands.

### Migration from `<= 0.2`

Until version `0.2`, CDKTN only supported a single stack. For local state handling, CDKTN used a `terraform.tfstate` in the project root folder. With version `>= 0.3`, the local state file reflects the stack name it belongs to in its file name. When a `terraform.tfstate` file is still present in the project root folder, it has to be renamed to match the schema `terraform.<stack-name>.tfstate` manually.

## Escape Hatch

For anything on the top-level `terraform` block that is not natively implemented, use the **stack escape hatch** to define a configuration. For example, define remote backend using the `addOverride` method in TypeScript.

<Warning>Escape hatches **must not** have empty arguments or objects, because CDKTN removes them from the synthesized JSON configuration.</Warning>

The following example synthesizes a Terraform configuration with the `remote` backend included in the `terraform` block.

<CodeGroup>
  ```ts TypeScript theme={null}
  stack.addOverride("terraform.backend", {
    local: null, // delete the default local backend
    remote: {
      organization: "test",
      workspaces: {
        name: "test",
      },
    },
  });
  ```

  ```java Java theme={null}
  stack.addOverride("terraform.backend", new HashMap<String, HashMap<String, Object>>() {
      {
          put("local", null); // delete the default local backend
          put("remote", new HashMap<String, Object>() {
              {
                  put("organization", "test");
                  put("workspaces", new HashMap<String, String>() {
                      {
                          put("name", "test");
                      }
                  });
              }
          });
      }
  });
  ```

  ```python Python theme={null}
  stack.add_override("terraform.backend", {
      "local": Token.null_value(), # delete the default local backend
      "remote": {
          "organization": "test",
          "workspaces": {
              "name": "test"
          }
      }
  })
  ```

  ```csharp C# theme={null}
  stack.AddOverride("terraform.backend", new Dictionary<string, object> {
      {"local", null}, // delete the default local backend
      {"remote", new Dictionary<string, object> {
          {"organization", "test"},
          {"workspaces", new Dictionary<string, string> {
              {"name", "test"}
          }}
      }}
  });
  ```

  ```go Go theme={null}
  stack.AddOverride(jsii.String("terraform.backend"), map[string]interface{}{
  	"local": cdktn.Token_NullValue(), // delete the default local backend
  	"remote": map[string]interface{}{
  		"organization": "test",
  		"workspaces": map[string]string{
  			"name": "test",
  		},
  	},
  })
  ```
</CodeGroup>

The following configuration snippet shows the `remote` backend configuration.

```json theme={null}
{
  "terraform": {
    "required_providers": {
      "aws": "~> 2.0"
    },
    "backend": {
      "remote": {
        "organization": "test",
        "workspaces": {
          "name": "test"
        }
      }
    }
  }
}
```
