The primary feature of Pretf is to read * files and create matching *.tf.json files. These JSON files are supported by Terraform as an alternative to the more commonly used *.tf files.

Start by creating a file named in your Terraform project directory:


from pretf.api import block

def pretf_blocks():
    yield block("resource", "random_integer", "dog", {
        "min": 1,
        "max": 10,

    yield block("resource", "random_integer", "cat", {
        "min": 1,
        "max": 10,

    yield block("resource", "random_integer", "buffalo", {
        "min": 1,
        "max": 10,

The function must be named pretf_blocks() for Pretf to find it.

Now run pretf validate, which will generate a JSON file, run terraform validate, and clean it up afterwards:

$ pretf validate
[pretf] create:
[pretf] run: terraform validate
Success! The configuration is valid.

If you saw:

Error: provider.random: no suitable version installed
  version requirements: "(any version)"
  versions installed: none

Then you probably need to run pretf init to install the Random provider. This is standard Terraform behaviour and nothing to do with Pretf, except that Pretf runs Terraform . Run pretf init and then pretf validate again.

With Terraform successfully validating your generated JSON file, you can now run pretf plan or pretf apply to manage the new resources. You can still run terraform directly, but using pretf as a wrapper will ensure that generated JSON files are always up to date.

The 'yield' keyword

If you are not familiar with the yield keyword in the above code, then read about Python Generators introduced in Python 2.2. Normally we might create a list, append elements to that list, and then return the list at the end of the function. Instead, we can just yield each element as we go.

Translate HCL to Python

Translating HCL code into Python block objects is very simple. They are constructed in the same way as the original HCL, only requiring slight adjustments to be valid Python syntax.

The following HCL resource consists of a block type resource, labels random_integer and dog, and the body { min = 1, max = 10 }.

resource "random_integer" "dog" {
  min = 1
  max = 10

Simply translate each part into a valid Python type and pass it into the block() function:

block("resource", "random_integer", "dog", {
    "min": 1,
    "max": 10,