Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't use Bash parameter expansion #15933

Closed
ghost opened this issue Aug 26, 2017 · 3 comments
Closed

Can't use Bash parameter expansion #15933

ghost opened this issue Aug 26, 2017 · 3 comments
Labels

Comments

@ghost
Copy link

ghost commented Aug 26, 2017

Terraform Version

Terraform v0.9.8

Terraform Configuration Files

#...
# 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

Crash Output

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 ":"

Expected Behavior

I expect that the variable username is set to depoly, using mywiki.wooledge.org/BashGuide/Parameters#Parameter_Expansion

Actual Behavior

Terraform thinks that every ${*} should be "substituted"

Steps to Reproduce

Render a template file that includes a variable with parameter expansion like the above

References

Didn't found

@apparentlymart
Copy link
Member

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.

@ghost
Copy link
Author

ghost commented Aug 27, 2017

awesome, @apparentlymart!
I'll close the issue as I used the workaround that you proposed.

@ghost ghost closed this as completed Aug 27, 2017
@ghost
Copy link

ghost commented Apr 7, 2020

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.

@hashicorp hashicorp locked and limited conversation to collaborators Apr 7, 2020
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

1 participant