runatlantis/atlantis

Different Terraform versions

Closed this issue ยท 2 comments

Community Note

  • Please vote on this issue by adding a ๐Ÿ‘ reaction to the original issue to help the community and maintainers prioritize this request. Searching for pre-existing feature requests helps us consolidate datapoints for identical requirements into a single place, thank you!
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request.
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment.

Overview of the Issue

From built-in step

- plan

Results in Terraform 1.9.6

From custom step

- run: terraform plan -input=false -refresh -out $PLANFILE

Results in Terraform 1.9.5

So if I use both

โ•ท
โ”‚ Error: Failed to read plan from plan file
โ”‚ 
โ”‚ Cannot read the plan from the given plan file: plan file was created by
โ”‚ Terraform 1.9.5, but this is 1.9.6; plan files cannot be transferred
โ”‚ between different Terraform versions.
โ•ต

Reproduction Steps

Logs

Environment details

Atlantis v0.29.0

Additional Context

Hello @hakuno! I'm here to help you with any bugs, questions, or contributions you have. Let's tackle this Terraform version issue together while we wait for a human maintainer.

I found a similar open issue that might be relevant to your problem: Using previous versions of Terraform no longer works. This issue was last updated on June 27, 2024, and currently has no comments or solution [1].

To resolve the error "Failed to read plan from plan file" when using different Terraform versions (1.9.5 and 1.9.6) in Atlantis v0.29.0, you need to ensure that the plan file is compatible with the Terraform version being used. The error typically occurs because the plan file generated by one version of Terraform is not readable by another version.

Here are some steps to ensure compatibility:

  1. Use the same Terraform version for both planning and applying: Ensure that the Terraform version used to create the plan file is the same as the one used to apply it. This can be managed by setting the TerraformVersion in the ProjectContext.

  2. Check for remote operations: If using Terraform Cloud or Enterprise, ensure that the remote operations are correctly handled, as the plan file might not be saved locally.

Here is a snippet from the planStepRunner that shows how the plan command is built and executed:

func (p *planStepRunner) Run(ctx command.ProjectContext, extraArgs []string, path string, envs map[string]string) (string, error) {
    tfVersion := p.DefaultTFVersion
    if ctx.TerraformVersion != nil {
        tfVersion = ctx.TerraformVersion
    }

    planFile := filepath.Join(path, GetPlanFilename(ctx.Workspace, ctx.ProjectName))
    planCmd := p.buildPlanCmd(ctx, extraArgs, path, tfVersion, planFile)
    output, err := p.TerraformExecutor.RunCommandWithVersion(ctx, filepath.Clean(path), planCmd, envs, tfVersion, ctx.Workspace)
    if p.isRemoteOpsErr(output, err) {
        ctx.Log.Debug("detected that this project is using TFE remote ops")
        return p.remotePlan(ctx, extraArgs, path, tfVersion, planFile, envs)
    }
    if err != nil {
        return output, err
    }
    return p.fmtPlanOutput(output, tfVersion), nil
}

Ensure that the TerraformVersion in the ProjectContext is set correctly to match the version used for both planning and applying. If you are using remote operations, the remotePlan method will handle the creation of a "fake" plan file to ensure compatibility [2].

Additionally, you can enforce the use of a specific Terraform version across all steps by setting the --default-tf-version flag or specifying the terraform_version key in the atlantis.yaml file for a specific repo or project.

Example using --default-tf-version flag:

--default-tf-version=v1.3.7

Example using atlantis.yaml:

version: 3
projects:
- dir: .
  terraform_version: v1.1.5

Alternatively, you can use the required_version key in the Terraform configuration block to specify an exact version or a version constraint.

Example using required_version in Terraform configuration:

terraform {
  required_version = "= 1.2.9"
}

Atlantis will automatically download the latest version that fulfills the specified constraint [3][4].

To continue talking to Dosu, mention @dosu.

So I see
It needs to append an environment variable as terraform${ATLANTIS_TERRAFORM_VERSION}