1. Overview

Terraform is an Infrastructure-as-Code (IaC) tool that enables us to provide and maintain infrastructure, especially in the cloud. It has a simple declarative language, HashiCorp Configuration Language (HCL). The infrastructure components used in Terraform, like resources, have several attributes, or arguments. Sometimes, we may need to learn which attributes a resource has, what an attribute’s type is, and more.

In this tutorial, we’ll discuss how to list the attributes of a Terraform resource. The version of Terraform we use is 1.8.2.

2. Example Configuration

We’ll use a Terraform configuration that writes Hello Baeldung to the /tmp/hello_baeldung.txt file:

$ cat hello_baeldung.tf
resource "local_file" "hello_baeldung" {
    content = "Hello Baeldung\n"
    filename = "/tmp/hello_baeldung.txt"
    file_permission = "0744"
}

Here, we’re using the Terraform configuration file hello_baeldung.tf. The type of resource we use in this file is local_file, which is used to generate a file with the specified content. Our resource’s name is hello_baeldung.

We specify the file’s content using the content attribute of local_file, whereas we use the filename attribute to name the file. Finally, we use the file_permission attribute to set the permissions of /tmp/hello_baeldung.txt. As we’ll see shortly, there are also other arguments of the local_file resource, which we don’t specify in hello_baeldung.tf.

3. Using Provider Documentation

Terraform providers supply information about resource types and their arguments in the Terraform registry. Each resource has a documentation page. For example, we can view the provider documentation for the local_file resource:

HashiCorp Local File

The Schema section provides a short explanation of each attribute, together with its type. Schemas define the fields of a resource or other Terraform objects together with the metadata of those fields.

For example, filename is a required attribute, and its type is string. However, content is an optional attribute, and its type is also string. Therefore, using provider documentation on the web is one way to get information about the attributes of a resource.

4. Using terraform console

Using the terraform console command is another option to get the attributes of a resource. terraform console provides an interactive console for running Terraform expressions:

$ terraform console
>

The arrowhead symbol, >, shows that terraform console is ready for running expressions. We can use the exit command or press Ctrl+C or Ctrl+D to close the console.

Notably, we need to initialize the configuration once using terraform init before we run terraform console. Otherwise, running terraform console gives an error.

Let’s use the type() function in the console to get a resource’s attributes and their corresponding types:

$ terraform console
> type(local_file.hello_baeldung)
object({
    content: string,
    content_base64: string,
    content_base64sha256: string,
    content_base64sha512: string,
    content_md5: string,
    content_sha1: string,
    content_sha256: string,
    content_sha512: string,
    directory_permission: string,
    file_permission: string,
    filename: string,
    id: string,
    sensitive_content: string,
    source: string,
})
>

Since the type of our resource is local_file and its name is hello_baeldung, we pass local_file.hello_baeldung as an argument to the type() function. As we see in the output, local_file has fourteen attributes. The arguments we specify in hello_baeldung.tf, namely content, filename, and file_permission, are naturally among the attributes. All attributes in this case are of the string type.

Importantly, we need to deploy the configuration before using the type() function. That means we need to run the terraform apply command beforehand. Otherwise, we can’t get the list of arguments.

5. Using terraform providers schema

Another alternative for listing the attributes of a resource is to use the terraform providers schema command. This command prints the details of the schemas of the providers used in the current configuration.

Let’s use it on our configuration:

$ terraform providers schema -json | jq
{
  "format_version": "1.0",
  "provider_schemas": {
    "registry.terraform.io/hashicorp/local": {
      "provider": {
        "version": 0,
        "block": {
          "description_kind": "plain"
        }
      },
      "resource_schemas": {
        "local_file": {
          "version": 0,
          "block": {
            "attributes": {
              "content": {
                "type": "string",
                "description": "Content to store in the file, expected to be a UTF-8 encoded string.\n Conflicts with `sensitive_content`, `content_base64` and `source`.\n Exactly one of these four arguments must be specified.",
                "description_kind": "plain",
                "optional": true
              },
...

Since the output is long, we’ve truncated it. The terraform providers schema command requires the -json option to print the output in JSON format. However, it prints the JSON string on a single line. So, we pass the output to the jq command using a pipe to pretty-print it.

The attributes of the local_file resource are listed within the attributes field starting with the “attributes”: { line in the output. The first attribute is content. The content field in the JSON output has several fields. For example, the type of the attribute is string according to the “type”: “string” line, while specifying this attribute in the Terraform configuration file is optional according to the “optional”: true line in the output.

Therefore, the information about the attributes of a resource can be found within the output of the terraform providers schema command.

5.1. Filtering the Output Using jq

We can further process the information in the JSON output for our needs. For example, we can list all the attributes of a resource together with their corresponding types:

$ terraform providers schema -json | jq -r '.provider_schemas["registry.terraform.io/hashicorp/local"].resource_schemas.local_file.block.attributes | keys[] as $k | "\($k), \(.[$k] | .type)"'
content, string
content_base64, string
content_base64sha256, string
content_base64sha512, string
content_md5, string
content_sha1, string
content_sha256, string
content_sha512, string
directory_permission, string
file_permission, string
filename, string
id, string
sensitive_content, string
source, string

The first part of the command preceding the pipe, terraform providers schema –**json, is the same as before. We filter the JSON output using jq after the pipe in the second part. The -r option of jq displays raw output — so, the result isn’t displayed as a JSON string with quotes.

The .provider_schemas[“registry.terraform.io/hashicorp/local”].resource_schemas.local_file.block.attributes part of the filter lists all the attributes of local_file, together with all attribute fields.

Additionally, the keys[] as $k | “\($k), \(.[$k] | .type)” part filters the type field of each attribute and prints the attribute name together with the type.

Consequently, we’re successful in displaying all the attributes of a Terraform resource using terraform providers schema and jq.

We need to download the providers in a configuration using terraform init before running terraform providers schema. Otherwise, it gives an error:

$ terraform providers schema -json | jq
terraform providers schema -json | jq
╷
│ Error: Inconsistent dependency lock file
│ 
│ The following dependency selections recorded in the lock file are inconsistent with the current configuration:
│   - provider registry.terraform.io/hashicorp/local: required by this configuration but no version is selected
│ 
│ To make the initial dependency selections that will initialize the dependency lock file, run:
│   terraform init

Using terraform providers schema may be more practical than terraform console since we can get the attributes of a resource before deploying it using terraform apply.

6. Conclusion

In this article, we discussed how to list the attributes of a Terraform resource. We learned that it’s possible to get the attributes of a resource using the resource’s page on the Terraform registry. Then, we saw that we could use the interactive terraform console command to get the attributes of a resource together with the corresponding type. We used the type() function for this purpose. Finally, we learned that using the terraform providers schema command together with the jq command is another option.