Answers: <p>I don't think there are any best practices because it would depend on both your company structure as well as how your developers manage their code in SCM (gitflow, trunk, etc).</p>
  <p>Lets start with the statements that seem to be in contradiction. I think quoted like that they do seem to tell a different story. But lets look at the start of the paragraph where the first quote came from.</p>
  <blockquote>
  <p>When Terraform is used to manage larger systems, teams should use
  multiple separate Terraform configurations that correspond with
  suitable architectural boundaries within the system so that different
  components can be managed separately and, if appropriate, by distinct
  teams.</p>
  </blockquote>
  <p>So it's saying that when you have multiple teams using the same terraform directory (aka configuration) then...</p>
  <blockquote>
  <p>Workspaces alone are not a suitable tool for system decomposition, because each subsystem should have its own separate configuration and backend, and will thus have its own distinct set of workspaces.</p>
  </blockquote>
  <p>Which makes sense. Each team will need different things from their workspace and since all the teams will be sharing workspaces then it kinda falls apart. So in conclusion, different directories and workspaces can be used to separate environments in Terraform but they have certain limitations. In the tutorial you linked, I think it's explained even better:</p>
  <blockquote>
  <p>To separate environments with potential configuration differences, use
  a directory structure. Use workspaces for environments that do not
  greatly deviate from one another, to avoid duplicating your
  configurations.</p>
  </blockquote>
  <p>The second part of your question about recommendations can get somewhat complicated depending on what level of CICD and automation your company currently has. If your infra is small and the number of changes every month is pretty minimal then it's probably fine to just checkout the code, make the change and deploy it locally.</p>
  <p>But if you are a large organization with 100's of changes a week, then you are probably going to want to automate the deployments. A common way of doing that is to trigger CICD on new PR's or changes to certain branches. From there you can have your CICD engine change workspaces based on the branch name. Or more commonly for older companies who used Terraform before workspaces existed, you can just set the state path to something like <code>${env}/tf.state</code> because that really has the same effect as just using workspaces.</p>
  <p>I'm a Terraform and <a href="https://github.com/gruntwork-io/terratest/releases/tag/v0.28.5" rel="nofollow noreferrer">terratest</a> contribtutor. I'm also the author of <a href="https://github.com/DontShaveTheYak/cf2tf" rel="nofollow noreferrer">cf2tf</a> and the <a href="https://github.com/DontShaveTheYak/terraform-module-template" rel="nofollow noreferrer">terraform-module-template</a>.</p>
  
Answers: CC BY-SA 4.0
Answers: 2022-07-22T12:35:02.947Z
Answers: Thanks for your reply Levi. Eventually we went for separate directories containing separate statefiles, which works quite well for us.
Answers: Salmon
Answers: CC BY-SA 4.0
Answers: 2022-07-18T22:15:52.250Z
Answers: 2022-07-18T22:15:52.250Z
Answers: Levi
Body: <p>I want to separate my development stages in the TerraForm repository.</p>
  <p>The TerraForm <a href="https://www.terraform.io/language/state/workspaces" rel="nofollow noreferrer">workspaces page</a> states:</p>
  <p><em>&quot;Workspaces alone are not a suitable tool for system decomposition, because each subsystem should have its own separate configuration and backend, and will thus have its own distinct set of workspaces.&quot;</em></p>
  <p>However, many tutorials, like <a href="https://learn.hashicorp.com/tutorials/terraform/organize-configuration" rel="nofollow noreferrer">this one</a> state:</p>
  <p><em>&quot;There are two primary methods to separate state between environments: (...) and <strong>workspaces</strong>.&quot;</em></p>
  <p>Those two statements seem to be in contradiction. Could someone explain what the best practice is for stage separation? Currently I plan to use separate directories:</p>
  <pre><code>├── prod
  │   ├── main.tf (referencing the modules)
  │   ├── variables.tf
  │   ├── terraform.tfstate
  │   └── terraform.tfvars
  ├── dev
  │   ├── main.tf (referencing the modules)
  │   ├── variables.tf
  │   ├── terraform.tfstate
  │   └── terraform.tfvars
  └── modules
     ├── module A
     └── module B
  </code></pre>
  
Tags: <terraform><terraform-module><terraform-workspace>
Title: TerraForm separate stages
UserDisplayName: Salmon
ThreadText: # TerraForm separate stages
  
  (Asked by: username_0 on 2022-05-02)
  
  I want to separate my development stages in the TerraForm repository.
  
  The TerraForm [workspaces page](https://www.terraform.io/language/state/workspaces) states:
  
  *"Workspaces alone are not a suitable tool for system decomposition, because each subsystem should have its own separate configuration and backend, and will thus have its own distinct set of workspaces."*
  
  However, many tutorials, like [this one](https://learn.hashicorp.com/tutorials/terraform/organize-configuration) state:
  
  *"There are two primary methods to separate state between environments: (...) and **workspaces**."*
  
  Those two statements seem to be in contradiction. Could someone explain what the best practice is for stage separation? Currently I plan to use separate directories:
  
  ```
  ├── prod
  │   ├── main.tf (referencing the modules)
  │   ├── variables.tf
  │   ├── terraform.tfstate
  │   └── terraform.tfvars
  ├── dev
  │   ├── main.tf (referencing the modules)
  │   ├── variables.tf
  │   ├── terraform.tfstate
  │   └── terraform.tfvars
  └── modules
     ├── module A
     └── module B
  
  ```
  
  **Tags:** terraform, terraform-module, terraform-workspace
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2022-07-18. Score: 1
  
  I don't think there are any best practices because it would depend on both your company structure as well as how your developers manage their code in SCM (gitflow, trunk, etc).
  
  Lets start with the statements that seem to be in contradiction. I think quoted like that they do seem to tell a different story. But lets look at the start of the paragraph where the first quote came from.
  
  > When Terraform is used to manage larger systems, teams should use
  > multiple separate Terraform configurations that correspond with
  > suitable architectural boundaries within the system so that different
  > components can be managed separately and, if appropriate, by distinct
  > teams.
  
  So it's saying that when you have multiple teams using the same terraform directory (aka configuration) then...
  
  > Workspaces alone are not a suitable tool for system decomposition, because each subsystem should have its own separate configuration and backend, and will thus have its own distinct set of workspaces.
  
  Which makes sense. Each team will need different things from their workspace and since all the teams will be sharing workspaces then it kinda falls apart. So in conclusion, different directories and workspaces can be used to separate environments in Terraform but they have certain limitations. In the tutorial you linked, I think it's explained even better:
  
  > To separate environments with potential configuration differences, use
  > a directory structure. Use workspaces for environments that do not
  > greatly deviate from one another, to avoid duplicating your
  > configurations.
  
  The second part of your question about recommendations can get somewhat complicated depending on what level of CICD and automation your company currently has. If your infra is small and the number of changes every month is pretty minimal then it's probably fine to just checkout the code, make the change and deploy it locally.
  
  But if you are a large organization with 100's of changes a week, then you are probably going to want to automate the deployments. A common way of doing that is to trigger CICD on new PR's or changes to certain branches. From there you can have your CICD engine change workspaces based on the branch name. Or more commonly for older companies who used Terraform before workspaces existed, you can just set the state path to something like `${env}/tf.state` because that really has the same effect as just using workspaces.
  
  I'm a Terraform and [terratest](https://github.com/gruntwork-io/terratest/releases/tag/v0.28.5) contribtutor. I'm also the author of [cf2tf](https://github.com/DontShaveTheYak/cf2tf) and the [terraform-module-template](https://github.com/DontShaveTheYak/terraform-module-template).
  
  > **Comments:**
  > **username_0**: Thanks for your reply username_1. Eventually we went for separate directories containing separate statefiles, which works quite well for us.  
  
  ---
  
  