hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io/
Other
42.11k stars 9.47k forks source link

Support creating Terraform Cloud workspaces with local run via terraform init #24878

Open jen20 opened 4 years ago

jen20 commented 4 years ago

Current Terraform Version

Terraform v0.12.24

Use-cases

Executing terraform init with a remote backend configured and a workspace which does not yet exist creates the workspace in Terraform Cloud in Remote mode - similarly to if it were created via the Terraform Cloud interface with default settings. Subsequent operations on many Terraform configurations then fail thanks to missing credentials, and one must log into the web user interface to change the run mode to Local.

It would be useful to be able to specify via either backend configuration or a flag to init that a workspace is to be created in local mode to avoid this additional step.

Attempted Solutions

Nothing is listed in the documentation or CLI help about this - the current workaround is to log in to the web UI for each new workspace created.

pkolyvas commented 4 years ago

@jen20

Thanks for writing. Indeed, the remote backend does not currently support setting the execution mode of the workspace.

As a workaround, the Terraform Cloud provider has a tfe_workspace resource which will allow you to create or update workspaces with local operations enabled.

The documentation is lacking clarity in this area and I've got a PR open to fix it. Here's the relevant update section for you.:

operations - Indicates whether the workspace is using remote execution mode. Set to false to switch execution mode to local. true by default.

There are a couple of options at this point:

  1. Re-provision Terraform Cloud with Terraform using the Terraform Cloud provider. This will allow you to configure workspaces with the execution mode you expect, as well as create variables you might need.

  2. If you already have workspaces create and some configuration within you can import those workspace you've already initialized into another Terraform configuration and use the tfe_provider to update them in place.

I hope this is at least somewhat helpful in the meantime.

jen20 commented 4 years ago

Thanks for the reply - the workaround seems like more work for the limited number of workspaces I use than just logging into the web UI to change the options, which is what I've done for now.

It seems like a flag on terraform init or in the remote backend configuration would be the best resolution to this in future.

elijah-roberts commented 4 years ago

Agreed... think this relates to: https://github.com/hashicorp/terraform/issues/23261https://github.com/hashicorp/terraform/issues/23261

I currently have to hack around this in my pipeline by hitting the API directly:

export TF_FQWN=${TF_PREFIX}${TF_WORKSPACE}
 if $(curl --request GET --url https://app.terraform.io/api/v2/organizations/<orgname>/workspaces --header "authorization: Bearer $TF_CLOUD_TEAM_TOKEN" --header "content-type: application/vnd.api+json"
      | jq ".data | any(.attributes.name == env.TF_FQWN)");
      then echo "$TF_FQWN exists";
      else echo "creating workspace $TF_QWN" &&
      curl --request POST --url https://app.terraform.io/api/v2/organizations/<orgname>/workspaces
      --header "authorization: Bearer $TF_CLOUD_TEAM_TOKEN" --header "content-type: application/vnd.api+json"
      --data '{"data":{"attributes":{"name": "'"$TF_FQWN"'","operations":false},"type":"workspaces"}}';
      fi;

basically I create a fully qualified workspace name (TF_FQWN) by using the prefix + workspace i.e my-cool-service-prod

Then check if it exists, and if not create it, with operations:false

I would much prefer being able to set this in the backend:

terraform {
  backend "remote" {
    hostname     = "app.terraform.io"
    organization = "my-organization"

    workspaces {
      prefix = "my-cool-service-"
      mode = "local"
    }
  }
}
philippeckel commented 3 years ago

First of all, I've been using Terraform Cloud for a while now and in general I am quite happy with the product, as in general with most stuff HashiCorp release. So thanks a ton to HashiCorp for their awesome work; pushing DevOps, Infrastructure as Code, open-source etc.

But I assume this is purely a business instead of a technical decision to promote their remote mode which is working nicely as well. This might drag some folks away from setting up pipelines in Gitlab etc. if they only need to run Terraform it self.

And I get it from HashiCorp's perspective and I assume the API built behind Terraform Cloud already supports this, but it's just not accessible yet.

But there is also very good reasons for the local mode, be it runnning in a pipeline or even from a developer machine.

So as @elijah-roberts suggested, this should be implemented. And making this part of a paid plan is fine for me too.

The main problem is as already mentioned:

It's breaking with Infrastructure as Code.

Thanks for listening!