hashicorp / setup-terraform

Sets up Terraform CLI in your GitHub Actions workflow.
https://developer.hashicorp.com/terraform/tutorials/automation/github-actions
Mozilla Public License 2.0
1.33k stars 236 forks source link

Raw output when using wrapper with `$()` in bash #20

Closed allejo closed 8 months ago

allejo commented 4 years ago

I was in the process of migrating our workflows to use this new action for setting up terraform when I ran into this... behavior? bug? I'm not sure what to call it.

When terraform_wrapper is set to true (the default behavior) in this action, it breaks what would be considered normal behavior in bash.

Take the following example from a step in a workflow:

- run: echo "credentials: $(terraform output my_arn)" > my_file.txt

The contents of the file created would be this:

credentials: [command]/home/runner/work/_temp/<some UUID>/terraform-bin output my_arn

Instead of the expected:

credentials: my_arn_value

The only way to fix this problem is to set terraform_wrapper to false. I'm not sure if this is something that can be fixed/changed? Otherwise, I think it would be a good idea to put this somewhere in the README.

/cc @petersin0422

benc-uk commented 3 years ago

Same This had me pulling my hair out for about 3 hours why the output terraform output always contained a load of gibberish!

It renders $(terraform output foo) impossible to use 😥

NillsF commented 3 years ago

Came to this comment since I am dealing with the same issue. I was a little confused by @allejo's comment on wrapper, but was able to figure it out:

If you want to be able to use terraform output, use the following terraform setup step in your action:

    - name: Setup Terraform
      uses: hashicorp/setup-terraform@v1
      with:
        terraform_wrapper: false
volkorny commented 3 years ago

If disabling the wrapper is not good for your case you can use this horrible workaround:

     - name: Terraform Output
        id: get_ip
        run: terraform output instance_ip

      - name: Trim Output 
        uses: frabert/replace-string-action@v1.1
        id: trim
        with:
          pattern: '/(\n+)/'
          string: '${{ steps.get_ip.outputs.stdout }}'
          replace-with: ''

      - name: Add url to file
        run: echo "http://${{ steps.trim.outputs.replaced }}:${{ env.APP_PORT }}${{ env.APP_URI }}" >> file.txt
tony84727 commented 3 years ago

Run into this too. And I need the wrapper so disabling it is not an option. I found when creating the wrapper, the action actually renames the original terraform to terraform-bin: https://github.com/hashicorp/setup-terraform/blob/4c5048fbafdfd6bbe1a1e41f79f54413dfd28c6d/lib/setup-terraform.js#L122-L128 So another workaround will be changing terraform to terraform-bin to use the terraform binary directly.

In the context of @allejo 's issue, it should be echo "credentials: $(terraform-bin output my_arn)" > my_file.txt

skeggse commented 3 years ago

This ate up a good chunk of time for me. IMO this is surprising/unexpected behavior, and I'd love it if we disabled the wrapper by default. That said, it sounds like plenty of folks do derive value from the wrapper, though if you just throw setup-terraform in your workflow and expect it to give you a normal terraform binary you'll be sorely disappointed.

mattmichal commented 2 years ago

I have a workflow with some steps that leverage the features of the wrapper but I also needed the clean JSON plan output to use with infracost. This is the workaround that I used:

- name: Terraform show
  id: show-json
  if: github.ref != 'refs/heads/main'
  # terraform_wrapper adds GH-related text to stdout (debug, outputs, etc.)
  # the wrapper is required for other steps (fmt, init, validate) so it cannot be disabled
  # use sed to pull the second line of the file which, for this command, is the only line that is valid
  run: terraform show -json terraform.plan | sed -n 2p > terraform.plan.json

This will have to be adjust if the wrapper ever changes but this is good enough for now.

NathanielRN commented 2 years ago

I also ran into this issue, but for some reason doing the terraform output -raw my-value in another step seemed to work. Would be nice if we could have a command line flag to disable the wrapper temporarily so we can do manipulations on the data in one step!

An example of what I had to do:

- name: Extract SDK layer arn
  id: extract-arn
  run: terraform output -raw arn
- name: Set SDK layer version output
    # NOTE: If I try to do this and the above step in the same step,
    # I get garbage wrapper text in my variable!
  run: |
    arn_version=$(echo "${{ steps.extract-arn.outputs.stdout }}" | cut -d : -f 8)
    echo $arn_version
eclosson commented 2 years ago

I ran into this issue too, disabled the wrapper to work around it. I don't use the wrapper so wasn't an issue. Posting to help keep this issue alive as this was unexpected behavior that took a bit to sort out.

My vote would be to disable terraform_wrapper by default. If not a good option for most, next best thing would be a flag to the wrapper that disables the stdout capture/mod.

Example:

website_uri=$(terraform --nowrap output -raw website_uri)
solarmosaic-kflorence commented 2 years ago

When handling expected failures with terraform ... || terraform ... I wanted to ignore the core.setFailed due to the first command failing. The solution in https://github.com/hashicorp/setup-terraform/issues/20#issuecomment-723853380 worked great (using terraform-bin instead of terraform just for the case that could potentially fail). Would be great to have the ability to run commands without the wrapper become an actual feature so it doesn't break at some point.

slalomark commented 2 years ago

I think it's rather incredible that this isn't mentioned in the Readme at all as well. Generating Terraform Outputs for use in later steps is a very likely use case in a CICD situation. Dumping an entire stdout and filtering through that to get your Output value is not really practical.

schlomo commented 1 year ago

FYI, to temporarily disable - unwrap - the wrapper, I use this Bash script fragment:

if type -p terraform-bin ; then
    echo "Unwrapping terraform wrapper :-)"
    shopt -s expand_aliases
    unalias -a
    alias terraform=terraform-bin
fi
air3ijai commented 1 year ago

https://github.com/hashicorp/setup-terraform/issues/167#issuecomment-1090760365

terraform-bin output instance_id
austinvalle commented 8 months ago

This issue will be fixed in an upcoming v3.0.0 release next week. Please see this comment for more info

github-actions[bot] commented 1 month ago

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.