Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE]: Terraform workspace support #2024

Closed
Pacobart opened this issue Aug 28, 2020 · 6 comments · Fixed by #2150
Closed

[FEATURE]: Terraform workspace support #2024

Pacobart opened this issue Aug 28, 2020 · 6 comments · Fixed by #2150

Comments

@Pacobart
Copy link

Feature Request

Background / Motivation

We use terraform workspaces to manage state across multiple deployment environments. Currently, this requires running a custom exec module with the commands to create/select workspaces.

kind: Module
type: exec
name: tf-tasks
local: true
exclude: ['*']
tasks:
  - name: tf-workspace-init
    command: ["terraform workspace new ${var.deployEnv} || terraform workspace select ${var.deployEnv}"]

What should the user be able to do?

In the terraform module allow setting the workspace name statically or via variable.

Why do they want to do this? What problem does it solve?

When using the exec module the commands don't always run as intended causing us to manually run commands prior to using garden commands. This feature also aligns with terraform being a first class citizen in garden.

Suggested Implementation(s)

kind: Module
type: terraform
name: tf-infra
autoApply: true
allowDestroy: true
workspaceName: ${var.deployEnv}
include: ['*']

How important is this feature for you/your team?

🌵 Not having this feature makes using Garden painful

@elijah-roberts
Copy link

@Pacobart I also ran into this issue and resolved it this way:

---
kind: Module
type: exec
name: tf-tasks
local: true
exclude: ['*']
tasks:
  - name: tf-workspace-set
    command: ["echo ${var.deployEnv} > .terraform/environment"]
---
kind: Module
type: terraform
name: tf-infra
autoApply: true
allowDestroy: true
include: ['*']
dependencies:
  - tf-workspace-set

Based on the recommendation here: https://support.hashicorp.com/hc/en-us/articles/360043550953-Selecting-a-workspace-when-running-Terraform-in-automation
Basically this works because of the order of operations for garden and terraform....
garden does the initial init which for the s3 backend, defaults to default workspace.
The dependency for my terraform step, ensures that I update .terraform/environment after the init (so I do not run into trouble using a workspace that had not been defined yet), but before my plan/apply so that my state is actually stores in S3 env/${var.deployEnv}...

This satisfies my goal, of having a user install just garden, pull down a repo, and run garden deploy... with out having to manage, kubectl, terraform, etc dependencies...

this all said... first class support for workspaces would be good, and is still a valid feature... and you may end up implementing it in a similar way by managing the .terrform/environment file directly...

@elijah-roberts
Copy link

elijah-roberts commented Sep 2, 2020

As discussed in this thread: https://kubernetes.slack.com/archives/CKM7CP8P9/p1598982704073300

There are some inconsistencies with how the terraform backends works with workspaces.

In the case of S3 there is a default workspace named default and you have to init using that workspace, then you can create a workspace (workspace command fails if you have not done an init).

The way we git around this in our other pipelines is

echo "1" | terraform init -upgrade -no-color 

This passes an input value to the backend to select the 1st workspace which is default for the init
but because I have TF_WORKSPACE= when I run the plan, and apply it will override it....

Example:

export TF_WORKSPACE=ejr5001
terraform init
Initializing modules...
Initializing the backend...
The currently selected workspace (ejr5001) does not exist.
  This is expected behavior when the selected workspace did not have an
  existing non-empty state. Please enter a number to select a workspace:
  1. default

  Enter a value:

With our work around

export TF_WORKSPACE=ejr5001
echo "1" | terraform init
Initializing modules...
Initializing the backend...
Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "datadog" (terraform-providers/datadog) 2.12.1...
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.datadog: version = "~> 2.12"
Terraform has been successfully initialized!

but because TF_WORKSPACE is set... a show will indicated that it has been overridden:

terraform workspace show
ejr5001

Because of this difference, it might be necessary to ensure that garden knows the type of backend used, whether via a scan and pulling it automagically, or having the user set a field value.

But in the case of S3 it is possible to run the init command with the default setting, and then create the .terraform/environment file based on the workspace field.

If garden wanted to handle this issue and support the TF_WORKSPACE variable... they could have a field S3InitDefaultWorkspace: true that would basically duplicate the logic I have above running the typescript equivalent of

echo "1" |  terraform init

@elijah-roberts
Copy link

@edvald FYI

@stale
Copy link

stale bot commented Nov 2, 2020

This issue has been automatically marked as stale because it hasn't had any activity in 60 days. It will be closed in 14 days if no further activity occurs (e.g. changing labels, comments, commits, etc.). Please feel free to tag a maintainer and ask them to remove the label if you think it doesn't apply. Thank you for submitting this issue and helping make Garden a better product!

@stale stale bot added the stale Label that's automatically set by stalebot. Stale issues get closed after 14 days of inactivity. label Nov 2, 2020
@Pacobart
Copy link
Author

Pacobart commented Nov 2, 2020

@edvald We still believe this is a needed feature and aligns with the strategy of Terraform being a first class citizen in Garden.

@stale stale bot removed the stale Label that's automatically set by stalebot. Stale issues get closed after 14 days of inactivity. label Nov 2, 2020
@edvald
Copy link
Collaborator

edvald commented Nov 2, 2020

Agreed! Stalebot being a little over-eager there.

edvald added a commit that referenced this issue Nov 25, 2020
You can now set the `workspace` field on the Terraform provider as well
as on `terraform` modules. When set, Garden will select (creating if
necessary) the specified Terraform workspace ahead of applying,
planning, destroying etc.

Closes #2024
edvald added a commit that referenced this issue Nov 30, 2020
You can now set the `workspace` field on the Terraform provider as well
as on `terraform` modules. When set, Garden will select (creating if
necessary) the specified Terraform workspace ahead of applying,
planning, destroying etc.

Closes #2024
edvald added a commit that referenced this issue Nov 30, 2020
You can now set the `workspace` field on the Terraform provider as well
as on `terraform` modules. When set, Garden will select (creating if
necessary) the specified Terraform workspace ahead of applying,
planning, destroying etc.

Closes #2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants