Search code examples
terraformterraform-template-file

Terraform : using the file provisionner on a remote connection with a template causes an error


I am using terraform version 1.13.0 and am having trouble using the combination of file provisionner, remote connection and template file

In my scenario, I create a rabbitmq broker and a CentOS virtual machine, I then use a template file in order to upload a script to the VM that will contain the url of the broker

This however causes an error that is displayed in french ( no clue why ) and looking for it or translating it does not seem to be of any value

Here is my terraform file that causes the error :

terraform {
  required_providers {
    template = {
      source = "tfregistry.cloud.socgen/hashicorp/template"
    }
    null = {
      source = "tfregistry.cloud.socgen/hashicorp/null"
    }
    cloudplatform = {
      source = "tfregistry.cloud.socgen/XXX"  # provider made by the company I work for
    }
  }
}

resource "cloudplatform_postgre_cluster" "cluster" {
  # ressource made by the company I work for
}

resource "null_resource" "file_config" {
  connection {
    type        = "ssh"
    user        = "XXX"
    host        = cloudplatform_postgre_cluster.cluster.host
    private_key = file(var.XXX)
  }
  provisioner "file" {
    source      = templatefile("ansible/test.tfpl", {
      hello     = "tada"
    })
    destination = "~/test.sh"
  }
}

The VM gets created correctly, the connection works, I can upload non template files and use them no problem on the VM and the template also works just fine using the "local_file" ressource but when I attempt to run the shown terraform script I get the following error :

null_resource.file_config: Creating...
null_resource.file_config: Provisioning with 'file'...
╷
│ Error: file provisioner error
│
│   with null_resource.file_config,
│   on provisionners.tf line 39, in resource "null_resource" "file_config":
│   39:   provisioner "file" {
│
│ CreateFile 1
│ 2 tada
│ 3
│ : La syntaxe du nom de fichier, de répertoire ou de volume est incorrecte.
╵

I'm very unsure as to why the error is in french but all of the rest is in english ( would prefer english )

As you can see the template seems to work just fine but it cannot be uploaded. What am I doing wrong ?


Solution

  • This error message appears to be the French language localization of the message for the Windows API error code 123, ERROR_INVALID_NAME.

    I believe the equivalent of this message on English-localized Windows systems would be something like "The filename, directory name, or volume label syntax is incorrect.".

    This error message is being returned by the underlying operating system, and so it's using the language your OS is configured to use. I assume your local system is running a version of Windows, even though your target system is running CentOS, and so that suggests that the problem is happening locally on your system rather than remotely in your virtual machine.

    I think the problem here is that you've assigned your template result to the source argument instead of the content argument, and so the provisioner thinks you are trying to use the template result as the path to an already-existing file to upload, rather than a local file. That then fails because your template result includes characters that are not permitted in filenames on Windows; I assume it's complaining about the newline characters.

    If you change to using the content argument instead of the source argument then I think this should work the way you intended.

      provisioner "file" {
        content = templatefile("ansible/test.tfpl", {
          hello = "tada"
        })
        destination = "~/test.sh"
      }
    

    I would suggest considering the advice in Provisioners are a Last Resort though, since this seems like an example of Running configuration management software.