Terraform: Quiet flag for plan command

Created on 27 Oct 2017  Â·  16Comments  Â·  Source: hashicorp/terraform

Currently, terraform plan outputs a lot of "noise". For example:

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

data.terraform_remote_state.foundation: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...
data.template_file.bootstrap: Refreshing state...

Often when making changes to our Terraform code, I will run terraform plan before and after making the change and compare the output in order to verify that the change is working as intended. This output, however, makes it harder for me to do so. It would be great if there was a -quiet flag that could be used to suppress this output.

cli enhancement

Most helpful comment

Oh, aha! So this is another place we need to update the output to use the resource addressing syntax. (We did this for apply and plan output in a recent release, but missed "refresh" I suppose.)

All 16 comments

Hi @joshuaspence!

I'm not sure why you're seeing the same resource mentioned multiple times for refreshing. That's some strange behavior that I don't have any explanation for. The output here should be more like:

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

data.terraform_remote_state.foundation: Refreshing state...
data.external.ec2_instance_info: Refreshing state...
data.template_file.bootstrap: Refreshing state...

With that said, I think if we were to do this we'd want to use a more specific option name, like maybe -refresh=quiet as an alternative to -refresh=false, since "quiet" isn't really clear about what exactly it silences. I'd love to first be able to explain why the output here is so repetitive, though... :thinking:

Oh, it's not really the same resource... we have a module that we use which essentially provides a wrapper around the aws_instance resource. Two of the things that this module does is lookup the current on-demand price for the specified instance type (this is data.external.ec2_instance_info) and provide a bootstrap script that we use for provisioning the instances (data.template_file.bootstrap). So the repeated resources in the provided output are all coming from a different resource being created with our module. Although, this presents another issue, perhaps, in that the output doesn't provide fully-qualified resource names which can make it hard to debug.

Oh, aha! So this is another place we need to update the output to use the resource addressing syntax. (We did this for apply and plan output in a recent release, but missed "refresh" I suppose.)

fwiw, Landscape is a good solution to this:

$ terraform plan | landscape
No changes.

We have a lot of resources too. And our build pipeline consists from group of Terraform parts. _It is very difficult to review multiple plans across hundreds of lines._

Landscape is ruby tool. We have CI and also allow different engineers to run our pipeline too. They all have different environments on their workplaces. Installation of one more tool for large team of poorly connected people with absolutely different technical skills is a pain. We are using only Gradle + Terraform. Landscape is suitable only for advanced users.

Landscape is suitable only for advanced users.

I beg to differ - it's quite simple, as I showed in my example above.
Though I understand it would be much nicer to have it as a native Terraform solution - nevertheless that's probably not going to happen soon so it's instead available today in a third-party tool 😄

If installing Ruby is a problem, stick it in a Docker container. In fact, a Dockerfile is provided. You could use Bash aliases to make the docker run -i --rm landscape shorter and easier to remember too.

With that said, I think if we were to do this we'd want to use a more specific option name, like maybe -refresh=quiet as an alternative to -refresh=false, since "quiet" isn't really clear about what exactly it silences.

This is exactly what I was hoping to find — I'm running Terraform against a large number of AWS accounts and refreshes account for almost all of the output produced. It'd be really nice if there was a way to have that be silent unless an error occurs.

You could redirect the output to script variable or temp file, then if the return status is non-zero echo it to stderr, e.g. something like

$ response=$(terraform plan 2>&1) || echo $response 1>&2

Is there any update on this request? I also find plans to be quite noisy, including when you're rendering a local file. +1

+1 to this as well. we generate a tfplan while running plan. so, if there's an optional way to suppress the logging on stdout that'll be very nice indeed.

+1 agreed there is not much value of this output to the standard user

This is useful with https://terraform-compliance.com/ as it requires you to generate a plan file to test against. Helps cut back on the noise when you need to run plans against multiple envs are part of the test suite.

This was an issue for me while using github actions. The output of the plan became to large to postback to the pull request. To solve my issue, I did a refresh before the plan, then omitted the refresh from the plan step

terraform refresh
terraform plan -refresh=false

+1 there is not much value of this output to the standard user

FYI to people in this thread - with 0.14 refactoring the way that plans refresh the current state, @jbardin noted a few downsides to the refresh then plan workflow and @apparentlymart provided this alternative that avoids those downsides. For local development, creating an alias for this command will provide the same functionality that people currently get from refreshing before planning.

terraform plan -out=tfplan >/dev/null && terraform show tfplan && rm tfplan

FYI to people in this thread - with 0.14 refactoring the way that plans refresh the current state, @jbardin noted a few downsides to the refresh then plan workflow and @apparentlymart provided this alternative that avoids those downsides. For local development, creating an alias for this command will provide the same functionality that people currently get from refreshing before planning.

terraform plan -out=tfplan >/dev/null && terraform show tfplan && rm tfplan

n.b. this has a few drawbacks since anything which causes a prompt will display on stdin and the process will appear to have hung. I also changed it so the rm is always run to avoid leaving tfplan files behind:

terraform plan -input=false -out=tfplan >/dev/null && terraform show tfplan ; rm tfplan

(You could probably avoid the temporary file by duplicating stdout before redirecting it but that doesn't seem worth the loss of clarity)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ncraike picture ncraike  Â·  77Comments

felnne picture felnne  Â·  133Comments

bloopletech picture bloopletech  Â·  82Comments

glenjamin picture glenjamin  Â·  112Comments

mirogta picture mirogta  Â·  74Comments