如何比较两个 Terraform 计划的差异?

huangapple go评论43阅读模式
英文:

How to compare two Terraform plans for differences?

问题

有一个流水线生成Terraform计划并在经理批准更改之前暂停。它可以花费不确定的时间来批准(一秒,三小时等),因此提议的Terraform计划可能会因多种原因而不同,比如基础架构被手动修改(不是故意的,但可能发生)。

在批准后,流水线运行第二个Terraform计划,并将其与预批准阶段生成的第一个计划进行比较。流水线使用git diff进行比较,如果有差异,则失败。这不符合预期,因为计划即使在一起生成后,也会有差异,在一个称为relevant_attributes的部分,但差异在于生成JSON的顺序,而不是内容或有效更改。

以下脚本用于生成JSON并进行比较:

terraform show -json expected.tfplan | jq . > expected.json
terraform show -json actual.tfplan | jq . > actual.json
git diff --no-index expected.json actual.json || exit 1

这种方法是否有修复方法?或者在这种批准场景中,是否有更好的方法来比较两个Terraform计划的差异?

英文:

There is a pipeline that generates a Terraform plan and pauses until a manager approves the changes. It can pass an undetermined period of time for it to be approved (one second, three hours, etc) so the proposed Terraform plan could differ from the Terraform plan executed after the approval due to many reasons like the infrastructure being manually modified (not intended but possible).

The pipeline after the approval runs the second Terraform plan and compares it with the first one generated in the pre-approval stage. The pipeline does the comparison with a git diff and fails if there is a difference. That is not working as expected because the plans differ even if generated one after the other, in a section called relevant_attributes, but the differences are the order in which the JSON is generated, not the content or effective changes.
如何比较两个 Terraform 计划的差异?

The following scripts are being used to generate the JSONs and compare them out:

terraform show -json expected.tfplan | jq . > expected.json
terraform show -json actual.tfplan | jq . > actual.json
git diff --no-index expected.json actual.json || exit 1

Is there a fix for this approach? Alternatively, are there better ways to compare two Terraform plans for differences in this approval scenario?

答案1

得分: 1

以下是翻译好的部分:

You can export your plan with -out=PLAN_FILE and then only apply it when you want.
(你可以使用 -out=PLAN_FILE 导出计划,然后只在需要时应用它。)

For example, you can run
(例如,你可以运行)

terraform plan -out tfplan.zip

To show the plan you can run
(要显示计划,你可以运行)

terraform show tfplan.zip

Then when you want to apply you just run terraform apply PLAN_FILE
(然后当你想要应用时,只需运行 terraform apply PLAN_FILE

terraform apply tfplan.zip

Or you can go for other approaches, for example by using approval features on some CI/CD platforms (circleci, or GitHub Actions's deployments for example) where you block the apply step and keep your pipeline pending.
(或者你可以采用其他方法,例如使用一些 CI/CD 平台上的审批功能(例如 circleciGitHub Actions 的部署),在那里你可以阻止应用步骤并保持管道挂起。)

Or simply treat your IaC as we would treat our code, only deploy when merging to some branches; makes your main branches protected and only require approvals from authorized people. When opening a PR run a simple Terraform plan, and when it gets merged you run terraform apply.
(或者简单地将你的 IaC 对待方式与我们对待代码的方式一样,只有在合并到某些分支时才部署;将你的 main 分支设置为受保护,并只需要经过授权人员的批准。在打开 PR 时运行简单的 Terraform 计划,当它被合并时运行 terraform apply。)


Edit:

Apparently, these solutions might not fit your use case, so your approach might be better, you just need to sort your resource_change array with jq in case it gets shuffled between each plan
(显然,这些解决方案可能不适合你的用例,所以你的方法可能更好,只需使用 jq 对你的 resource_change 数组进行排序,以防在每个计划之间发生混乱)

terraform show -json expected.tfplan | jq '.resource_changes | sort_by(.address)'

(运行上述命令以排序 expected.tfplan 文件中的 resource_changes 数组)

英文:

You can export your plan with -out=PLAN_FILE and then only apply it when you want.

For example, you can run

terraform plan -out tfplan.zip

To show the plan you can run

terraform show tfplan.zip

Then when you want to apply you just run terraform apply PLAN_FILE

terraform apply tfplan.zip

Or you can go for other approaches, for example by using approval features on some CI/CD platforms (circleci, or GitHub Actions's deployments for example) where you block the apply step and keep your pipeline pending.

Or simply treat your IaC as we would treat our code, only deploy when merging to some branches; makes your main branches protected and only require approvals from authorized people. When opening a PR run a simple Terraform plan, and when it gets merged you run terraform apply.


Edit:

Apparently, these solutions might not fit your use case, so your approach might be better, you just need to sort your resource_change array with jq in case it gets shuffled between each plan

 terraform show -json expected.tfplan | jq '.resource_changes | sort_by(.address)'

huangapple
  • 本文由 发表于 2023年2月16日 03:52:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75464818.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定