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
42.53k stars 9.52k forks source link

Add -out option to apply command #31366

Open gidonk-pr opened 2 years ago

gidonk-pr commented 2 years ago

Current Terraform Version

v1.2.1

Use-cases

Mainly Report Generation.

Currently in "plan" command you can use the -out option to output the plan to a file that can be used for the apply stage. this file can also be parsed to an HTML format report. (for example: https://github.com/cloudandthings/terraform-pretty-plan that we use)

We would like to have the same option when executing the apply command directly. The current '-json' command is not informative enough as it does not show the 'before' and 'after' of each resource like the plan does.

Having to first use the plan command (with the -out option) and then the apply command (with the -plan option) is not always a possible scenario (specifically when using terragrunt run-all apply commands: https://github.com/gruntwork-io/terragrunt/issues/720#issuecomment-497888756)

apparentlymart commented 2 years ago

Hi @gidonk-pr! Thanks for sharing this use-case.

Could you say a little more about what exactly you'd expect to find in a "saved apply file"? The saved plan file is a serialization of a real data structure Terraform uses to describe a set of actions internally, but there isn't any comparable internal data structure for the apply phase except the new state snapshots it creates, which you can retrieve using terraform show -json. Is there something specific missing from the combination of that output and the terraform apply -json progress reports that you need for your application?

gidonk-pr commented 2 years ago

what I mean - is that in the plan output includes a key named change which looks like so:

"change": {
        "actions": [
          "create"
        ],
        "before": null,
        "after": {
          "policy_arn": "XXXXXXXXX",
          "role": "XXXXXX"
        },
        "after_unknown": {
          "id": true
        },
        "before_sensitive": false,
        "after_sensitive": {}
      }

This format allows for detailed easy to view reports that will show the exact changes that took place. here is a snippet of the report that we generated (using terraform-pretty-plan):

Screen Shot 2022-07-06 at 16 10 27

The output from the apply command does not contain the information in a structure that allows for this report to run, and the show command displays the current applied state and no previous state.

apparentlymart commented 2 years ago

Thanks for the extra context, @gidonk-pr.

What I understand, then, is that you're running terraform apply without passing a saved plan file and so that command includes both a plan phase and an apply phase, and what you want is to retroactively access the plan Terraform generated during the plan phase, even though it was already applied and would therefore not be valid to pass to terraform apply because the actions described in it were already taken.

Is that correct way to understand what you're hoping for here?

gidonk-pr commented 2 years ago

@apparentlymart yes :)

apparentlymart commented 2 years ago

Great, thanks for your patience while I made sure I understood you correctly!

I expect if we were going to do this we'd probably want to name the option something different like -plan-out=... in this case, just because it doesn't feel super clear to me that the output of an apply operation should be the plan.


I do want to be up front that I don't expect we would prioritize designing and implementing this right now because there is already a documented and working mechanism to achieve this result in Terraform, and it seems like you are only unable to use it because you've chosen to run Terraform with some wrapping software that makes it harder to access some of Terraform's existing features so perhaps there is a path to that wrapping software supporting your use-case with the Terraform functionality that already exists.

For example, it could itself potentially wrap the terraform plan -out=tfplan and then terraform apply tfplan workflow, presumably using a different generated filename for each plan file if there's a need to generate many of them all at once, which would be functionally equivalent to saving the same plan file from the apply step as you've proposed here; other automation wrapped around Terraform is typically designed in this way, for the same reason, based on the documented Automated Terraform CLI Workflow.