> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Installing OpenTofu and HashiCorp Configuration Language HCL Basics

> Guide to installing OpenTofu, HCL basics, resource blocks, and the tofu init plan apply show workflow for provisioning and inspecting infrastructure.

In this lesson we recap how to install OpenTofu and introduce the basics of HashiCorp Configuration Language (HCL). You'll learn how to get the OpenTofu binary on your PATH, what HCL resource blocks look like, and the core OpenTofu workflow for provisioning resources.

OpenTofu binaries are distributed as pre-built releases for multiple platforms (Linux, macOS, Solaris, OpenBSD). After placing the binary in a directory on your `PATH`, verify installation with `tofu version` before proceeding to provisioning.

## Install the OpenTofu CLI

Downloading and installing OpenTofu is typically a matter of fetching the release archive for your platform, extracting the binary, and moving it into a directory on your `PATH`. For example, on a Linux amd64 host:

```bash theme={null}
wget https://github.com/opentofu/opentofu/releases/download/v1.6.1/tofu_1.6.1_linux_amd64.zip
unzip tofu_1.6.1_linux_amd64.zip
sudo mv tofu /usr/local/bin/
tofu version
```

Example output:

```console theme={null}
OpenTofu v1.6.1 on linux_amd64
```

Once the binary responds to `tofu version`, you're ready to write HCL and provision infrastructure.

## HCL (HashiCorp Configuration Language) basics

OpenTofu configuration files use HCL and typically have the `.tf` extension. HCL is declarative and organized with blocks and arguments:

* Blocks declare infrastructure elements (for example: `provider`, `resource`, `module`).
* Arguments within blocks are key = value pairs that configure the block.

A simple example that creates a local file (save as `local.tf`):

```hcl theme={null}
resource "local_file" "pet" {
  filename = "/root/pets.txt"
  content  = "We love pets!"
}
```

Key points:

* Blocks are delimited by `{ ... }`.
* The `resource` block begins with the keyword `resource`, followed by the resource type and a resource name.
  * Resource type here is `"local_file"`. The portion before the underscore (`local`) indicates the provider; the portion after (`file`) is the resource kind.
  * `"pet"` is a logical name you choose to reference the resource in your configuration.
* Inside the block, `filename` and `content` are arguments specific to the `local_file` resource.

Another example (S3 bucket):

```hcl theme={null}
resource "aws_s3_bucket" "data" {
  bucket = "webserver-bucket-org-2207"
  acl    = "private"
}
```

The structure is identical: `resource` keyword → resource type (`aws_s3_bucket`) → resource name (`data`) → provider-specific arguments.

What is a resource?

* A resource is an object OpenTofu manages. Examples include local files, compute instances (EC2), cloud storage (S3), IAM users, serverless functions, and more. OpenTofu supports many resource types exposed by community and vendor providers.

How do you know which arguments a resource supports?

* OpenTofu reuses providers compatible with Terraform. Consult the provider documentation in the Terraform Registry for the full resource catalog and argument details:
  * Terraform Registry: [https://registry.terraform.io/](https://registry.terraform.io/)

Each provider maintains its own resource catalog and argument set (AWS, GCP, Azure, etc.), so consult the provider docs when authoring configurations.

![A diagram comparing cloud providers that maps a "Provider" to "Resource\_type" and corresponding "Arguments," with AWS and Google Cloud service icons shown in separate columns. The left side shows the provider/resource/arguments flow while the middle and right display example AWS and GCP resource icons.](https://mintcdn.com/kodekloud-c4ac6d9a/6iY8H-GlEe_e7L62/images/OpenTofu-A-Beginners-Guide-to-a-Terraform-Fork-Including-Migration-From-Terraform/Getting-Started-with-OpenTofu/Installing-OpenTofu-and-HashiCorp-Configuration-Language-HCL-Basics/aws-gcp-resource-mapping-diagram.jpg?fit=max\&auto=format\&n=6iY8H-GlEe_e7L62\&q=85\&s=e08722017d7b7d0fa4efb0a908762702)

## Core OpenTofu workflow

A typical OpenTofu workflow has four main steps:

1. Write one or more configuration files (`*.tf`).
2. Initialize the working directory with `tofu init`.
3. Review the execution plan with `tofu plan`.
4. Apply the changes with `tofu apply`.

Table: Common OpenTofu commands

| Command | Purpose | Example / Notes |
| -: | - | - |
| `tofu init` | Initialize working directory and download providers | Detects providers and installs plugins (creates `.terraform.lock.hcl`) |
| `tofu plan` | Show execution plan without making changes | Preview resources to be added/changed/destroyed |
| `tofu apply` | Apply the planned changes | Interactive confirmation; use `-auto-approve` to skip prompt |
| `tofu show` | Inspect resource state | Prints the current state of resources in the directory |

### Initialize the directory

Using the `local_file` example, first initialize:

```bash theme={null}
$ tofu init
```

Example output (truncated):

```console theme={null}
Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/local...
- Installing hashicorp/local v2.4.1...
- Installed hashicorp/local v2.4.1 (signed, key ID 0C0AF313E5FD9F80)

Providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://opentofu.org/docs/cli/plugins/signing/

OpenTofu has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that OpenTofu can guarantee to make the same selections by default when
you run "tofu init" in the future.

OpenTofu has been successfully initialized!
```

`tofu init` detects referenced providers and downloads the provider plugins needed to execute your configuration.

### Plan: preview changes

Preview actions with:

```bash theme={null}
$ tofu plan
```

Example plan output (truncated):

```console theme={null}
OpenTofu used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
  + create

OpenTofu will perform the following actions:

  # local_file.pet will be created
  + resource "local_file" "pet" {
      + content               = "We love pets!"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "/root/pets.txt"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Note: You didn't use the -out option to save this plan, so OpenTofu can't guarantee to take exactly these actions if you run "tofu apply" now.
```

* The `+` indicates resources that will be created.
* The plan shows both declared arguments and computed attributes (e.g., file permissions).

Remember: `tofu plan` only shows what will happen; it does not change anything.

### Apply: make changes

When you're satisfied with the plan, apply it:

```bash theme={null}
$ tofu apply
```

You will be shown the plan again and prompted to confirm. Type `yes` to proceed.

Example interactive session (truncated):

```console theme={null}
Do you want to perform these actions?
OpenTofu will perform the actions described above.
Only 'yes' will be accepted to approve.

Enter a value: yes

local_file.pet: Creating...
local_file.pet: Creation complete after 0s [id=cba595b7d9f94ba1107a46f3f731912d95fb3d2c]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
```

You can bypass the confirmation prompt with:

```bash theme={null}
tofu apply -auto-approve
```

Use `-auto-approve` carefully. It bypasses the confirmation prompt and will immediately apply whatever actions are in the plan. As a best practice, always review the plan before applying changes.

### Inspecting state

After applying, inspect the latest state:

```bash theme={null}
$ tofu show
```

Example `tofu show` output for the local file (truncated and reformatted):

```console theme={null}
# local_file.pet:
resource "local_file" "pet" {
  content                 = "We love pets!"
  content_base64sha256    = "zUA5Ip/IeKImTQIp...Bp0c="
  content_base64sha512    = "tduqTz5S8Wa3O9Ab5+g0GcGL6kMjM...bjGg=="
  content_md5             = "f510a471c5dc0bcd4759ad9dc81a516f"
  content_sha1            = "cba595b7d9f94ba1107a46f3f731912d95fb3d2c"
  content_sha256          = "cd4039229fc878a9664d0229b65a7dd0974c18077c60b4ad0d78691aad01a747"
  content_sha512          = "b5dbaa4f3e52f166b73bd01be7e83419c18bea4323321eb5be315c326e4a90e3..."
  directory_permission    = "0777"
  file_permission         = "0777"
  filename                = "/root/pets.txt"
  id                      = "cba595b7d9f94ba1107a46f3f731912d95fb3d2c"
}
```

## Additional resources

* HCL documentation: [https://developer.hashicorp.com/hcl](https://developer.hashicorp.com/hcl)
* Terraform Registry (provider docs): [https://registry.terraform.io/](https://registry.terraform.io/)
* OpenTofu CLI docs: [https://opentofu.org/docs/cli/](https://opentofu.org/docs/cli/)

To recap:

* Use resource blocks to declare infrastructure objects.
* Inside resource blocks, use provider-specific arguments to define resource behavior.
* Run `tofu init`, `tofu plan`, and `tofu apply` to provision resources; use `tofu show` to inspect state.
* Always review the execution plan before applying changes.

That's it for this lesson. A future lesson will cover providers and provider plugins in more detail.

> **[Watch Video](https://learn.kodekloud.com/user/courses/opentofu-a-beginners-guide-to-a-terraform-fork-including-migration-from-terraform/module/b3a724ed-f2f2-4a25-a20e-bfb4c000d1e7/lesson/772acba8-ad6f-4352-aee5-ff432e2b561d)**


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.