Terraform v0.9.8
#...
# User data
data "template_file" "setup_server" {
template = "${file("../scripts/setup-server.sh")}"
vars {
project_name = "${var.project_name}"
aws_ecr_access_key = "${var.aws_ecr_access_key}"
aws_ecr_secret_key = "${var.aws_ecr_secret_key}"
}
}
#...
# ../scripts/setup-server.sh
username=${USERNAME:-deploy} # Line 9, where it encounters the error
main() {
create_user
configure_docker
make_app_dir
configure_ssh
install_awscli
configure_awscli
}
...
main
data.template_file.setup_server: Refreshing state...
Error refreshing state: 1 error(s) occurred:
* data.template_file.setup_server: 1 error(s) occurred:
* data.template_file.setup_server: data.template_file.setup_server: failed to render : parse error at 9:20: expected "}" but found ":"
I expect that the variable username is set to depoly, using mywiki.wooledge.org/BashGuide/Parameters#Parameter_Expansion
Terraform thinks that every ${*} should be "substituted"
Render a template file that includes a variable with parameter expansion like the above
Didn't found
Hi @MrOutis,
Sequences that look like interpolation sequences can be escaped by doubling the quotes:
username=$${USERNAME:-deploy}
To reduce the impact of such conflicts, I usually recommend splitting the logic and the variables into two separate files. The template would then just be a wrapper around the main script, which is uploaded verbatim without any template processing.
If having the result split into two separate files is not acceptable, an alternative is to have the main body of the script in a separate file _within the Terraform config_ and then insert it as a template variable:
data "template_file" "setup_server" {
template = "${file("../scripts/setup-server.sh.template")}"
vars {
project_name = "${var.project_name}"
aws_ecr_access_key = "${var.aws_ecr_access_key}"
aws_ecr_secret_key = "${var.aws_ecr_secret_key}"
logic = "${file("../scripts/setup-server-logic.sh")}"
}
}
The file setup-server.sh.template might then look something like this:
#!/usr/bin/env bash
PROJECT_NAME="${project_name}"
AWS_ACCESS_KEY_ID="${aws_ecr_access_key}"
AWS_SECRET_ACCESS_KEY="${aws_ecr_secret_key}"
${logic}
Since the file function doesn't do any sort of interpretation of the file being read (apart from assuming it's a UTF-8 encoded), any ${...} sequences in setup-server-logic.sh will then be left untouched.
awesome, @apparentlymart!
I'll close the issue as I used the workaround that you proposed.
I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
Most helpful comment
Hi @MrOutis,
Sequences that look like interpolation sequences can be escaped by doubling the quotes:
To reduce the impact of such conflicts, I usually recommend splitting the logic and the variables into two separate files. The template would then just be a wrapper around the main script, which is uploaded verbatim without any template processing.
If having the result split into two separate files is not acceptable, an alternative is to have the main body of the script in a separate file _within the Terraform config_ and then insert it as a template variable:
The file
setup-server.sh.templatemight then look something like this:Since the
filefunction doesn't do any sort of interpretation of the file being read (apart from assuming it's a UTF-8 encoded), any${...}sequences insetup-server-logic.shwill then be left untouched.