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

# Layer definitions

> Learn what are layer definitions and how they work.

<div className="flex justify-center items-center">
  <img src="https://mintcdn.com/ergomake-83/br_QNJl4feQWyGIg/images/bear-spawn.png?fit=max&auto=format&n=br_QNJl4feQWyGIg&q=85&s=30aaadbc4829fde772439996ee86296d" width="384px" data-path="images/bear-spawn.png" />
</div>

A layer definition is an entry in a JSON object. This entry includes a name, a list of dependencies, and the contents of the Terraform files Layerform will use to spawn infrastructure.

## Creating layer definitions

To create a layer definition, you need to start by creating a `layerform.json` file in the root folder of your project. It's in that folder that you'll run `layerform configure` to provision layers to the back-end.

In that file, each object within the `layers` array contains a layer definition with a name, list of files, and, optionally, a list of dependencies.

```json theme={null}
{
    "layers": [
        {
            "name": "base_example",
            "files": ["layers/base.tf", "layers/base/**"]
        },
        {
            "name": "your_top_layer",
            "files": ["layers/example.tf", "layers/example/**"],
            "dependencies": ["base_example"]
        }
    ]
}
```

Here's what each key is for:

1. `name`: an unique name for this layer definition. You'll use this name in the CLI to spawn instances of this layer definition.
2. `files`: a list of Terraform files included in this layer. Layerform will run these files to provision infrastructure for an instance of this layer definition.
3. `dependencies`: a list layer definition names upon which instances of the current layer will be placed.

**Once you have a `layerform.json` file, you should run `layerform configure` to upload the layer definitions to your Layerform back-end.**

<Note>
  [See this page to learn more about the multiple Layerform
  back-ends](./backends).
</Note>

### Creating Terraform files for layer definitions

**By convention, you should encapsulate your layer definitions' Terraform files into [Terraform modules](https://developer.hashicorp.com/terraform/language/modules).**

Encapsulating layer definitions into modules makes it easier to understand which files belong to each layer.

For example, if you have an `elastic_stack` layer, you'd have `kibana.tf` and `elasticsearch.tf` files within a folder called `elastic_stack`. That folder would also have any necessary inputs and outputs in `inputs.tf` and `outputs.tf` files.

```
layerform/
└─ elastic_stack/
    ├─ elasticsearch.tf
    ├─ kibana.tf
    ├─ inputs.tf
    └─ outputs.tf
```

Don't forget to also create an entry-point instantiating your module.

```
layerform/
├─ elastic_stack/
│   ├─ elasticsearch.tf
│   ├─ kibana.tf
│   ├─ inputs.tf
│   └─ outputs.tf
└─ entrypoint.tf <--- uses the module elastic_stack
```

This entrypoint should instantiate the module and pass the necessary inputs to it.

```hcl theme={null}
module "elastic_stack" {
    source = "./modules/elastic_stack"
    cluster_id = modules.eks.cluster_id
}
```

Then, when creating the entry in `layerform.json`, make sure to include both the entrypoint and all the files in the module's folder.

```jsonc theme={null}
{
    "layers": [
        // Don't forget to also add the base layer here
        {
            "name": "elastic_stack",
            "files": ["layers/example.tf", "layers/example/**"],
            "dependencies": ["base"]
        }
    ]
}
```

### Using variables across layer definitions

When using layer definitions, keep in mind that you can reference variables from another definition if, and only if, the reference variable belongs to the layer *below*.

For example, it's fine if your `elastic_stack` layer must take an `input` which comes from the `eks` module which is part of the underlying `eks` layer.

```hcl theme={null}
module "elastic_stack" {
    source = "./modules/elastic_stack"

    # This cluster_id reference comes from a file which
    # belongs to the underlying `eks` layer. That's fine.
    cluster_id = modules.eks.cluster_id
}
```

On the other hand, it's not fine if your `eks` layer references values from the `elastic_stack` layer on top of it.

```hcl theme={null}
# This code won't work
module "eks" {
    source = "./modules/eks"

    # This is NOT fine! Here, the reference comes from the
    # elastic_stack layer on *top*. Which won't be available.
    cluster_id = modules.elastic_stack.elasticsearch_url
}
```

<Tip>
  Encapsulating layers into modules makes it easier to understand whether
  you're referencing values in the layers below, above, or next to the target
  layer.
</Tip>

## Using layer definitions

Layer definitions are used by the Layerform CLI so it knows which Terraform files to run to create a layer instance. Layerform also looks at the `dependencies` list to fetch state for any underlying layers.

To use a layer definition, you must configure your CLI with the back-end containing the desired definition. For that, you must edit the `config.yaml` file within `~/.layerform`.

In that file, you should configure a context with the desired type and its settings. Then, you should set \`currentContext to the desired context's name.

```yaml theme={null}
currentContext: tutorial-context
contexts:
    tutorial-context:
        type: s3
        bucket: layerform-bucket-example
```

After that, you can spawn layers using `layerform spawn <layer_definition_name> <desired_id>`. The `layerform spawn` command will pull the matching definition from the specified context and run its Terraform files.

## Updating or deleting layer definitions

To update a layer definition, you must update the Terraform files associated with it and run `layerform configure` again. That will cause the Layerform CLI to update the back-end with your updated files.

To delete a particular layer definition, you can simply remove the corresponding entry from your `layerform.json` file and run `layerform configure` again.
