Answers: <p>You can use <a href="https://registry.terraform.io/providers/hashicorp/tfe/latest" rel="nofollow noreferrer">the Terraform Cloud provider</a> to manage workspace configuration in Terraform Cloud in the same way as you might manage any other infrastructure objects with Terraform. For historical reasons the provider is named <code>tfe</code>, but it can be used to manage both Terraform Enterprise and Terraform Cloud.</p>
  <p>In particular, you can use <a href="https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/resources/variable" rel="nofollow noreferrer">the <code>tfe_variable</code> resource type</a> to manage both Terraform variables and environment variables for a workspace:</p>
  <pre><code>variable &quot;environment_variables&quot; {
    type = map(string)
  }
  
  variable &quot;workspace_id&quot; {
    type = string
  }
  
  provider &quot;tfe&quot; {
    hostname = &quot;app.terraform.io&quot; # Terraform Cloud
  }
  
  resource &quot;tfe_variable&quot; &quot;test&quot; {
    for_each = var.environment_variables
  
    key          = each.key
    value        = each.value
    category     = &quot;env&quot;
    workspace_id = var.workspace_id
  }
  </code></pre>
  <p>To integrate this with the script you've already written, you could perhaps use PowerShell's JSON encoder to produce a file <code>azure.tfvars.json</code> with content like this:</p>
  <pre><code>{
    &quot;workspace_id&quot;: &quot;organization/workspace&quot;,
    &quot;environment_variables&quot;: {
      &quot;ARM_CLIENT_ID&quot;: &quot;...&quot;,
      &quot;ARM_CLIENT_SECRET&quot;: &quot;...&quot;,
      &quot;ARM_SUBSCRIPTION_ID&quot;: &quot;...&quot;,
      &quot;ARM_TENANT_ID&quot;: &quot;...&quot;
    }
  }
  </code></pre>
  <p>You can then run the above Terraform configuration using a command like this:</p>
  <pre><code>terraform apply -var-file=azure.tfvars.json
  </code></pre>
  <p>When considering automation of this sort it's worth considering where the Terraform state snapshots for this &quot;early&quot; Terraform configuration would live. You could potentially create an additional Terraform Cloud workspace for this special configuration and be sure to configure it to <em>not</em> use remote operations, so that a local run of this one workspace can then arrange for your other workspace to support remote operations.</p>
  
Answers: CC BY-SA 4.0
Answers: 2019-11-30T19:39:03.327Z
Answers: One thing that makes the cloud provider a bit difficult to work with. Like other terraform resources if the item exists already it will error out. Typically I would expect just to be able to override existing variables with the latest version as a variable to me is not something like a server. I'd expect to just update/override. The lack of a shared library for secrets or variables like azuredevops has makes this a little bit tricky to fully leverage
Answers: sheldonhull
Answers: CC BY-SA 4.0
Answers: 2019-11-25T18:03:18.523Z
Answers: 2023-06-02T20:14:48.840Z
Answers: 2023-06-02T20:14:48.840Z
Answers: Martin Atkins
Body: <p><a href="https://www.terraform.io/docs/cloud/index.html" rel="nofollow noreferrer">Terraform Cloud</a> is a SaaS platform for managing Terraform runs, state and variables.  Once you have created a project you can set environment variables via the following page:</p>
  
  <pre><code>https://app.terraform.io/app/[organization]/workspaces/[workspace]/variables
  </code></pre>
  
  <p><a href="https://i.sstatic.net/v02sC.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/v02sC.png" alt="Terraform Cloud Variables Page for Project"></a></p>
  
  <p>These environment variables are then set when Terraform executes a run.  Out of an abundance of a desire to automate this process, I have scripted the process of generating these environments variables:</p>
  
  <pre><code>$SubscriptionId = "&lt;subscription-id&gt;"
  $PrincipalName = "http://&lt;service-principal-name&gt;"
  $SubscriptionUrl = "/subscriptions/$SubscriptionId"
  
  az cloud set --name "AzureCloud" | Out-Null
  az account set --subscription $SubscriptionId | Out-Null
  
  $ServicePrincipal = az ad sp create-for-rbac --role="Owner" --scopes=$SubscriptionUrl --name $PrincipalName | ConvertFrom-Json
  
  $env:ARM_CLIENT_ID=$ServicePrincipal.appId
  $env:ARM_CLIENT_SECRET=$ServicePrincipal.password
  $env:ARM_SUBSCRIPTION_ID=$SubscriptionId
  $env:ARM_TENANT_ID=$ServicePrincipal.tenant
  </code></pre>
  
  <p>This works, however, I would like to extend the script to be able to push the variables to the appropriate Terraform Workspace.  I am aware that there is a <a href="https://www.terraform.io/docs/cloud/api/variables.html" rel="nofollow noreferrer">RESTful Variables API</a> that I can call although I was hoping for a solution that used the <code>terraform</code> command-line interface rather than relying on parsing <code>backend.tf</code> and calling a REST API from a script.</p>
  
Tags: <terraform><automation><terraform-workspace>
Title: How to set Terraform Cloud environment variables from the command line?
UserDisplayName: Richard Slater
ThreadText: # How to set Terraform Cloud environment variables from the command line?
  
  (Asked by: username_0 on 2019-11-22)
  
  [Terraform Cloud](https://www.terraform.io/docs/cloud/index.html) is a SaaS platform for managing Terraform runs, state and variables. Once you have created a project you can set environment variables via the following page:
  
  ```
  https://app.terraform.io/app/[organization]/workspaces/[workspace]/variables
  
  ```
  
  [![Terraform Cloud Variables Page for Project](https://i.sstatic.net/v02sC.png)](https://i.sstatic.net/v02sC.png)
  
  These environment variables are then set when Terraform executes a run. Out of an abundance of a desire to automate this process, I have scripted the process of generating these environments variables:
  
  ```
  $SubscriptionId = "<subscription-id>"
  $PrincipalName = "http://<service-principal-name>"
  $SubscriptionUrl = "/subscriptions/$SubscriptionId"
  
  az cloud set --name "AzureCloud" | Out-Null
  az account set --subscription $SubscriptionId | Out-Null
  
  $ServicePrincipal = az ad sp create-for-rbac --role="Owner" --scopes=$SubscriptionUrl --name $PrincipalName | ConvertFrom-Json
  
  $env:ARM_CLIENT_ID=$ServicePrincipal.appId
  $env:ARM_CLIENT_SECRET=$ServicePrincipal.password
  $env:ARM_SUBSCRIPTION_ID=$SubscriptionId
  $env:ARM_TENANT_ID=$ServicePrincipal.tenant
  
  ```
  
  This works, however, I would like to extend the script to be able to push the variables to the appropriate Terraform Workspace. I am aware that there is a [RESTful Variables API](https://www.terraform.io/docs/cloud/api/variables.html) that I can call although I was hoping for a solution that used the `terraform` command-line interface rather than relying on parsing `backend.tf` and calling a REST API from a script.
  
  **Tags:** terraform, automation, terraform-workspace
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2019-11-25. Score: 3 | Accepted answer
  
  You can use [the Terraform Cloud provider](https://registry.terraform.io/providers/hashicorp/tfe/latest) to manage workspace configuration in Terraform Cloud in the same way as you might manage any other infrastructure objects with Terraform. For historical reasons the provider is named `tfe`, but it can be used to manage both Terraform Enterprise and Terraform Cloud.
  
  In particular, you can use [the `tfe_variable` resource type](https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/resources/variable) to manage both Terraform variables and environment variables for a workspace:
  
  ```
  variable "environment_variables" {
    type = map(string)
  }
  
  variable "workspace_id" {
    type = string
  }
  
  provider "tfe" {
    hostname = "app.terraform.io" # Terraform Cloud
  }
  
  resource "tfe_variable" "test" {
    for_each = var.environment_variables
  
    key          = each.key
    value        = each.value
    category     = "env"
    workspace_id = var.workspace_id
  }
  
  ```
  
  To integrate this with the script you've already written, you could perhaps use PowerShell's JSON encoder to produce a file `azure.tfvars.json` with content like this:
  
  ```
  {
    "workspace_id": "organization/workspace",
    "environment_variables": {
      "ARM_CLIENT_ID": "...",
      "ARM_CLIENT_SECRET": "...",
      "ARM_SUBSCRIPTION_ID": "...",
      "ARM_TENANT_ID": "..."
    }
  }
  
  ```
  
  You can then run the above Terraform configuration using a command like this:
  
  ```
  terraform apply -var-file=azure.tfvars.json
  
  ```
  
  When considering automation of this sort it's worth considering where the Terraform state snapshots for this "early" Terraform configuration would live. You could potentially create an additional Terraform Cloud workspace for this special configuration and be sure to configure it to *not* use remote operations, so that a local run of this one workspace can then arrange for your other workspace to support remote operations.
  
  > **Comments:**
  > **username_2**: One thing that makes the cloud provider a bit difficult to work with. Like other terraform resources if the item exists already it will error out. Typically I would expect just to be able to override existing variables with the latest version as a variable to me is not something like a server. I'd expect to just update/override. The lack of a shared library for secrets or variables like azuredevops has makes this a little bit tricky to fully leverage  
  
  ---
  
  