hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io/
Other
41.7k stars 9.42k forks source link

Support custom output for plans #21300

Open alkalinecoffee opened 5 years ago

alkalinecoffee commented 5 years ago

Current Terraform Version

Terraform v0.11.13

Use-cases

We are exploring the use of terragrunt to wrap and clean up our terraform config. Currently, when running terraform plan, we can see the target module on which we are making changes as long as it's named properly:

Terraform will perform the following actions:

  ~ module.us_east_1_prod_blue.module.asg...

In using terragrunt, we no longer have stack-specific modules, as the base module is directly called. So running terraform plan does not clearly show us the stack we are managing:

Terraform will perform the following actions:

  ~ aws_autoscaling_group.autoscaling_group

Proposal

Terraform should allow for specifying any custom flags that should always be shown in the output.

$ terraform plan \
  -flag "the environment is prod" \
  -flag "the stack is blue" \
  -flag "for change ticket 1234"

------------------------------------------------------------------------

Flags:
  - the environment is prod
  - the stack is blue
  - for change ticket 1234

Terraform will perform the following actions:

  ~ aws_autoscaling_group.autoscaling_group

Providing the ability for the user to supply custom flags is helpful when sharing the plan with teammates to get feedback and +1s. Workspaces handle this by showing the current workspace value, which sort of helps, but this solution would be helpful to users that are not using workspaces or otherwise would like to include extra informational values as part of their plan.

apparentlymart commented 5 years ago

Hi @alkalinecoffee! Thanks for sharing this use-case.

At first glance, it seems like this is just a way to print out arbitrary text into the output of terraform plan. If that is so, could you not get the same effect by printing that information out directly from whatever program is launching Terraform?

e.g. in shell script:

echo "The environment is prod"
echo "The stack is blue"
echo "For change ticket 1234"
terraform plan

I was trying to think of situations where other similar software would provide a similar feature to this, but I couldn't think of one. If you have some examples of inspiration, that'd be helpful!

Since it's presumably Terragrunt that is responsible for setting these in your case, perhaps Terragrunt itself could be the one to print out this information, before it launches Terraform. I expect that'd be particularly helpful when using Terragrunt in the mode where it abstracts over running Terraform multiple times against different configurations, since it could then print out the information just once at the top and then all of the separate plans below.


Another thought that came to my mind as I was thinking about this request was that we could potentially have an option to print out the resolve input variable values as part of the plan output, which (depending on how the variables are set up) might expose the same information in a different way without needing to provide it to Terraform twice:

$ terraform plan -show-variables

Input Variables:
  environment = "prod"
  stack       = "blue"
  ticket_id   = 1234

# etc, etc normal plan output...

Having Terraform print out some information it already knows for other reasons feels different to me than asking it to just print out arbitrary information, because at least Terraform is doing some work in this case that the calling program couldn't necessarily just do itself.

I suppose if we were to do this then you could implement your "flags" idea in terms of it to include arbitrary data that wouldn't otherwise belong to a specific variable, if you wanted:

variable "flags" {
  type = any
  description = "Arbitrary extra information to attach to a Terraform plan"
}
$ terraform plan -show-variables -var="flags={environment=\"prod\", stack=\"blue\", ticket_id=1234}"

Input Variables:
  flags = {
    environment = "prod"
    stack       = "blue"
    ticket_id   = 1234
  }

# etc, etc normal plan output...
alkalinecoffee commented 4 years ago

Thanks for the feedback. We run terraform/terragrunt manually -- no other tools are used to make these plans so was hoping for a solution in terraform.

One workaround we're using now is to create a null_resource with triggers to show the relevant variables we want in the plan, ie

resource null_resource deploy_info {
  triggers {
    app = "${local.app}"
    env = "${local.env}"
    stack = "${local.stack}"
    timestamp = "${timestamp()}"
  }
}

This works okay, but since the null_resource will be shown on every run, terraform plan will never show green/no changes.

Maybe we could have some sort of flags resource, that acts similar to the output resource, which would always display the desired info like you have suggested, but without changing the actual plan. This way, values can be customized and not limited to just variables, ie

flag "appname" {
  value = "${var.app}"
}
$ terraform plan -var app=abc

Flags:
  appname = abc

------------------------------------------------------------------------

No changes. Infrastructure is up-to-date.

Will have to think about it a bit more.