hashicorp / terraform-provider-template

Terraform template provider
https://www.terraform.io/docs/providers/template/
Mozilla Public License 2.0
131 stars 89 forks source link

Invalid character; This character is not used within the language., and 4 other diagnostic(s) #50

Closed ghost closed 5 years ago

ghost commented 5 years ago

Hello

It seems like there was a change that occurred last night which caused my userdata template files to not render correctly.

My userdata template uses the line: $convertedByte=%{[System.Convert]::ToString($byte,16)} This has been rendering correctly, but as of last night, I began receiving this error:

data.template_file.ec2_instance_userdata: failed to render : :295,14-14: Invalid character; This character is not used within the language., and 4 other diagnostic(s).

If I lock the provider to 1.9.9 or under, using this code, then the template renders correctly.

> provider "template" {
  version = "<= 1.9.9"
}

Versions:

Thanks

Dicky

tmjd commented 5 years ago

I had a similar error message and had stuff in a template like

${ variable < 10 ? "the true" : "" }

and I found if I used the new construct for control (https://github.com/terraform-providers/terraform-provider-template/blob/master/CHANGELOG.md#200-january-14-2019) and switched to the new syntax (like below) then rendering worked again.

%{ if variable < 10 } the true %{ else } "" %{ endif }

Just thought I'd mentioned what worked for me in the hope that it helps someone.

pmoosh commented 5 years ago

also it break when I have a variable like: ${stuff.foo}

and errorred out at a comment in a template file like this (no quotes in original file): "# default_ccache_name = KEYRING:persistent:%{uid}" because of %{uid}

dylanhellems commented 5 years ago

From the change log:

... If your existing templates contain any %{ sequences you will need to now escape them as %%{ to ensure correct parsing.

Escaping with an extra '%' resolved a similar rendering issue that I was having.

pmoosh commented 5 years ago

@dylanhellems - thx. since it was in a comment. I simply just removed it. But going forward it might be a good idea for terraform to keep a compatibility matrix and not pull provider that knowingly break compatibility.

apparentlymart commented 5 years ago

Hi all! Sorry for the churn here.

This was a major release of the provider, which is how we communicate that breaking changes may be present. You can stay on the prior version if desired by using a version constraint, as recommended by terraform init:

provider "template" {
  version = "~> 1.0"
}

There are some items in the changelog describing some known incompatibilities in 2.0.0, including this one. Please also see #49 which covers a change we didn't anticipate due to an unknown bug in the old template engine; this one is not covered in the tagged release notes because we didn't know about it until after release.

pmoosh commented 5 years ago

@apparentlymart - I was just writing up a proposal over in terraform (as by browser crashed). If a provider breaks backward compatibility. It should not be downloaded and installed. For example terraform 0.11.x should not use template provider 2.0.

Pinning version has its own drawbacks (which is of course my own opinion).

apparentlymart commented 5 years ago

Hi @pmoosh,

As currently implemented, a version constraint like ~> is the way to constrain to a particular major version of a provider, and terraform init warns about this whenever it's run without a constraint:

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.template: version = "~> 1.0"

template provider 2.0.0 is compatible with Terraform 0.11, it's just not compatible with template provider 1.0.0. At this juncture the options are either to remain on version 1 or to update uses of the provider to accommodate the breaking changes in version 2 (and, in the process, get access to the new features that 2.0.0 introduces). Neither option requires you to upgrade Terraform itself.

We are planning, in a future release, to change the dependency handling of Terraform to generate such locks by default the first time a new provider is installed, requiring an explicit action for any future upgrade.

For now though, we recommend following the advice printed by terraform init to constrain each provider you use to the major version you are expecting. There will be other similar breaking provider releases in the near future that will also be accepted automatically by terraform init in the absence of these constraints.

apparentlymart commented 5 years ago

Hi all,

As I noted in my previous comment, pinning your version to ~> 1.0 is a way to keep the previous behavior if you don't wish to upgrade yet, and you can escape the control sequences with %%{ if you do wish to upgrade. Since this issue doesn't represent any specific work we could do to improve the situation, I'm going to close it out.