# Terraform & OpenTofu versions

Choose the tool for Terraform actions in Buddy: OpenTofu, open-source Terraform, or a custom binary in your own Docker image, and pin the version to run.

The native Terraform actions - Plan, Apply, and Drift Detection - run the tool you choose in the `tool` field:

| `tool` | Description |
| :--- | :--- |
| `OPENTOFU` | OpenTofu, supported out of the box |
| `TERRAFORM` | Open-source versions of Terraform, up to **1.5.7**, supported out of the box |
| `CUSTOM` | Any Terraform-compatible binary in your own Docker image |

## OpenTofu and Terraform

Buddy supports OpenTofu and the open-source versions of Terraform out of the box. Select the tool and the version you want to use - nothing else is needed.

```yaml
- action: Plan
  type: TERRAFORM_PLAN
  tool: OPENTOFU
  version: 1.12.6
```

`version` accepts:

- **A version number**, for example `1.12.6` for OpenTofu or `1.5.7` for Terraform. Recommended.
- **`latest`** - the newest release at the time of the run. The version can change between runs, so pin a specific version in production pipelines.
- **A variable**, for example `$TOFU_VERSION`, to share one version setting across pipelines.

To move from Terraform to OpenTofu, change `tool` to `OPENTOFU`, pick a version, and run Plan. OpenTofu reads the same `.tf` code and state. See the [OpenTofu migration guide](https://opentofu.org/docs/intro/migration/) for details specific to your Terraform version.

## Custom

The `CUSTOM` tool runs a binary from your own Docker image instead of one of the versions supported out of the box. Use it to:

- run a Terraform version that isn't supported out of the box,
- add tools the default images don't include, such as `aws`, `gcloud`, or `tflint`,
- bake in credentials or configuration for private modules,
- run a wrapper with a Terraform-compatible CLI.

## How it works

For `OPENTOFU` and `TERRAFORM`, each action runs in the official image of the tool - `ghcr.io/opentofu/opentofu:<version>` or `hashicorp/terraform:<version>` - with no extra tools added. The `version` value is used as the image tag.

For `CUSTOM`, the action runs in your image and calls the binary at `custom_binary_path`. The commands are the same as for the built-in tools - see [Plan and Apply](/docs/terraform/plan-and-apply.md) - so the binary must support:

- `init -input=false`
- `workspace show`
- `plan -input=false -out=<file> -json`
- `show -json`
- `apply -json -input=false <file>`

The version that actually ran is read from the plan and exported as `BUDDY_ACTION_TF_PLAN_TOOL_VERSION`, and the Apply and Drift Detection equivalents.

<Hint type="info">

Use the same tool and version in Plan and Apply. Apply works on the files and providers that Plan installed.

</Hint>

## How to configure a custom tool

Set `tool` to `CUSTOM`, point to the image, and give the path to the binary inside it:

| Field | Description |
| :--- | :--- |
| `custom_binary_path` | Path to the binary inside the image, for example `/usr/local/bin/terraform`. Required |
| `docker_image_name` | Image name. Required |
| `docker_image_tag` | Image tag |
| `image_location` | `PUBLIC_REGISTRY` or `PRIVATE_REGISTRY` |
| `docker_registry` | Registry type, for example `DOCKER_HUB`, `AMAZON_ECR`, `GIT_HUB_CONTAINER_REGISTRY`, or `OTHER` |
| `registry`, `login`, `password` | Registry address and credentials when `docker_registry` is `OTHER` |
| `integration`, `region` | Integration and region for registries like Amazon ECR |

With `CUSTOM`, the `version` field isn't used.

```yaml
- action: Plan
  type: TERRAFORM_PLAN
  tool: CUSTOM
  custom_binary_path: /usr/local/bin/terraform
  docker_image_name: my-org/terraform-toolbox
  docker_image_tag: 1.9.8
  image_location: PRIVATE_REGISTRY
  docker_registry: AMAZON_ECR
  integration: my-aws
  region: eu-central-1
  working_directory: infra
```

<Hint type="info">

The `integration` field on the action is only used to pull the image. Credentials for the state backend come from `backend.integration`. See [Credentials and variables](/docs/terraform/credentials-and-variables.md).

</Hint>

## Terraform CLI action

The [Terraform CLI action](/docs/terraform/terraform-cli.md) runs `hashicorp/terraform:<version>` and has no tool selection.

## Troubleshooting

Image pull errors, a missing custom binary, and a plan without a resource diff are covered in [Troubleshooting](/docs/terraform/troubleshooting.md#image-pull-fails).


---
Original source: https://buddy.works/docs/terraform/versions