Terraform 0.12.13 parses remote HCL variables during import
Local-only operations now preserve the meaning of workspace variables marked as HCL, and represent unavailable sensitive inputs as unknown values.
A workspace variable containing ["a", "b"] can mean either a list or a string containing list syntax. Terraform Cloud and Enterprise let users choose the intended interpretation with the HCL setting. Until this patch, local-only operations using the remote backend did not honor that setting, even though genuine remote plans and applies already did.
Terraform 0.12.13, released on October 31, corrects the local parsing path. The distinction explains why an import could fail on a structured variable in a workspace whose remote runs worked. The two operations obtained their inputs through different implementations.
I value the richer module interfaces in Terraform 0.12, particularly when they preserve the structure of infrastructure data. That benefit depends on values retaining their meaning across execution paths. A list should not become a string because an administrative command happens to run locally.
The reproduction is a type mismatch
Issue 23228, opened on October 29, describes a variable constrained as list(string). The corresponding workspace stores a list expression and marks it as HCL. A local-only command fetches the stored value, but the backend treats its text as a literal string.
The expected configuration input has this shape. Its type constraint describes a collection, independently of how the workspace stores its text.
variable "example" {
type = list(string)
}
The workspace's HCL value is a separate input. The following expression goes in the workspace value field with HCL selected.
["a", "b"]
Under the old local path, Terraform received text containing brackets and quotes instead of a collection with two string elements. Its type check then complained that the variable required a list of strings. The issue also records a misleading attribution to an environment variable, caused by the source classification used for the fetched value.
The variable's declaration was not the problem. Removing its type constraint would hide useful information about the mismatch without repairing the value. The missing step was parsing the stored expression according to the workspace's declared interpretation.
Remote and local operations load values differently
Martin Atkins explains the two paths in pull request 23229. For a remote operation, the hosted system writes stored values into a variable definitions file before running its copy of Terraform CLI. That processing already handles the HCL choice on the server.
A local-only operation such as import instead retrieves variables through the API and adds them directly to the local execution context. The previous code assumed they were all strings. Version 0.12.13 introduces a dedicated representation for remote stored variables that retains the HCL and sensitive flags when converting them into Terraform inputs.
An ordinary nonsensitive variable without the HCL flag remains a literal string. A nonsensitive HCL variable goes through the HCL expression parser and evaluator. This preserves the distinction users selected in the workspace instead of trying to infer a type from text that merely resembles an expression.
The release notes explicitly exclude true remote plan and apply operations from the fix's scope. Their variable processing remains on the remote system. This is a client correction for commands that construct a local context while using a remotely configured workspace.
HCL input is not an unrestricted configuration fragment
The new parser evaluates stored expressions without a context containing other variable names or function definitions. Its diagnostic requires literal expressions and rejects references to other variables or calls to functions. Marking an input as HCL lets it represent a structured value; it does not turn that field into a place to write arbitrary module logic.
That boundary is useful for understanding errors after the upgrade. A malformed HCL-marked value now fails when the local command parses workspace variables. Previously the command could pass the text through and succeed if its particular operation did not need the affected value.
The release describes the resulting error as an invalid expression for the named variable. It is possible for the corrected parser to reveal a preexisting invalid input. That does not mean the new parser changed a previously valid list into an error. It means the old local path had not attempted the interpretation selected by the workspace setting.
Sensitive inputs need an unknown value
The same patch repairs the representation of unavailable sensitive variables. Previously the local path substituted a fixed string marker. That marker could not satisfy a nonstring input type, causing an avoidable type error before the operation reached the place where the value might actually matter.
The new implementation uses an unknown value instead. If the variable is not HCL, Terraform can at least mark it as an unknown string. If it is HCL, the placeholder permits a value whose type has not yet been determined. Each unavailable sensitive input also produces a warning.
This does not retrieve the sensitive value or make it available locally. The patch deliberately allows an operation that does not depend on that value to continue, while warning that a later step requiring it may fail. Unknown information is represented as unknown information, instead of as a made-up string with an incompatible type.
I prefer this behavior because it separates absence from invalidity. A valid workspace can contain an input that the local command is not allowed to obtain. The command should preserve that distinction while checking everything it can check.
The patch also adds cleanup when context construction fails, so an error in this path does not simply leave the workspace locked. Together, these changes make local-only operations more consistent with the workspace's variable model. The local execution context can now use structured workspace inputs without misclassifying them as literal strings.