From 61389b28719b500e46196bfb412db79cce96891f Mon Sep 17 00:00:00 2001 From: Duncan F <131309315+duncanaf@users.noreply.github.com> Date: Sat, 31 Aug 2024 18:09:33 -0700 Subject: [PATCH] Support `atmos terraform apply --from-plan` with additional flags (#684) Right now, when atmos generates the plan-file arg for `terraform apply`, it puts it first, and then appends any additional args or flags that may be specified by the user. Terraform is very particular about the order of args and flags, and crashes with an error if flags follow the plan-file args. Instead, put the plan-file arg at the end of the command, after any additional flags or args. For example, with this change `atmos terraform apply -s $STACK $COMPONENT planfile -- -parallelism=1` will call `terraform apply -parallelism=1 planfile` instead of `terraform apply planfile -parallelism=1`. --- internal/exec/terraform.go | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/internal/exec/terraform.go b/internal/exec/terraform.go index e2931c6cb..1d2314100 100644 --- a/internal/exec/terraform.go +++ b/internal/exec/terraform.go @@ -345,15 +345,7 @@ func ExecuteTerraform(info schema.ConfigAndStacksInfo) error { case "refresh": allArgsAndFlags = append(allArgsAndFlags, []string{varFileFlag, varFile}...) case "apply": - if info.UseTerraformPlan { - if info.PlanFile != "" { - // If the planfile name was passed on the command line, use it - allArgsAndFlags = append(allArgsAndFlags, []string{info.PlanFile}...) - } else { - // Otherwise, use the planfile name what is autogenerated by Atmos - allArgsAndFlags = append(allArgsAndFlags, []string{planFile}...) - } - } else { + if !info.UseTerraformPlan { allArgsAndFlags = append(allArgsAndFlags, []string{varFileFlag, varFile}...) } case "init": @@ -370,6 +362,19 @@ func ExecuteTerraform(info schema.ConfigAndStacksInfo) error { allArgsAndFlags = append(allArgsAndFlags, info.AdditionalArgsAndFlags...) + // Add any args we're generating -- terraform is picky about ordering flags + // and args, so these args need to go after any flags, including those + // specified in AdditionalArgsAndFlags. + if info.SubCommand == "apply" && info.UseTerraformPlan { + if info.PlanFile != "" { + // If the planfile name was passed on the command line, use it + allArgsAndFlags = append(allArgsAndFlags, []string{info.PlanFile}...) + } else { + // Otherwise, use the planfile name what is autogenerated by Atmos + allArgsAndFlags = append(allArgsAndFlags, []string{planFile}...) + } + } + // Run `terraform workspace` before executing other terraform commands // only if the `TF_WORKSPACE` environment variable is not set by the caller if info.SubCommand != "init" && !(info.SubCommand == "workspace" && info.SubCommand2 != "") {