# Validate Configurations

# Validate Configurations

Before you deploy, you'll catch mistakes early. Atmos validates two things: that your **stack manifests** are well-formed (against a schema it ships with), and that your **component configuration** obeys rules you define — with [JSON Schema](https://json-schema.org/) for shape and [OPA policies](https://www.openpolicyagent.org/) for business logic.

By the end of this step you'll lint every stack with one command and block an invalid `s3-bucket` from ever being provisioned.

## Validate stack manifests

Atmos **ships the manifest JSON Schema embedded**, so linting every stack is a single command with nothing to configure:

```bash
atmos validate stacks
```

This checks that your manifests use valid sections and types. It's the fastest way to catch a typo'd key or a malformed import before it reaches Terraform.

:::note No schema to download
Older guides had you copy a `atmos-manifest.json` into the repo and point `schemas.atmos.manifest` (or `ATMOS_SCHEMAS_ATMOS_MANIFEST`) at it. That's no longer needed — Atmos validates against its built-in schema by default. You only configure `schemas` when you bring **your own** component schemas, below.
:::

## Validate component configuration

Beyond well-formed manifests, you can enforce rules on a component's actual configuration. Tell Atmos where your schemas live by adding a `schemas` section to `atmos.yaml`:

**File:** `atmos.yaml`

```yaml
schemas:
  jsonschema:
    base_path: "stacks/schemas/jsonschema"
  opa:
    base_path: "stacks/schemas/opa"
```

Then wire validation into a component's `settings.validation`. Here `s3-bucket` is checked by both a JSON Schema (shape) and an OPA policy (business rules):

**File:** `stacks/catalog/s3-bucket/defaults.yaml`

```yaml
components:
  terraform:
    s3-bucket:
      settings:
        validation:
          validate-s3-bucket-with-jsonschema:
            schema_type: jsonschema
            schema_path: "s3-bucket/validate-s3-bucket-component.json"
            description: Validate 's3-bucket' variables using JSON Schema
          check-s3-bucket-with-opa-policy:
            schema_type: opa
            schema_path: "s3-bucket/validate-s3-bucket-component.rego"
            module_paths:
              - "catalog/constants"
            description: Check 's3-bucket' configuration using OPA policy
            timeout: 10
```

### JSON Schema — validate shape

The JSON Schema checks the **shape** of the variables: the bucket `name` must be a lowercase slug of 2–40 characters, and `versioning_enabled` must be a boolean.

**File:** `stacks/schemas/jsonschema/s3-bucket/validate-s3-bucket-component.json`

```json
{
  "$id": "s3-bucket-component",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "vars": {
      "type": "object",
      "properties": {
        "name": { "type": "string", "minLength": 2, "maxLength": 40, "pattern": "^[a-z0-9-]+$" },
        "versioning_enabled": { "type": "boolean" }
      },
      "required": ["name", "versioning_enabled"]
    }
  }
}
```

### OPA — enforce business rules

The OPA policy encodes rules that span variables — most importantly, **in `prod`, S3 buckets must have versioning enabled**. Atmos reads the policy's `errors` array; any message there fails validation and the component won't provision.

**File:** `stacks/schemas/opa/s3-bucket/validate-s3-bucket-component.rego`

```
package atmos

# In production, S3 buckets must have versioning enabled.
errors[message] {
    input.vars.stage == "prod"
    input.vars.versioning_enabled != true
    message := "In 'prod', S3 buckets must have versioning enabled. Set 'versioning_enabled' to 'true'"
}
```

Validate a single component in a stack:

```bash
atmos validate component s3-bucket -s plat-ue2-prod
```

:::tip Notice how the rule is environment-aware
The same `s3-bucket` config passes in `dev` and fails in `prod` if versioning is off — because the OPA policy reads `input.vars.stage`. Validation runs against the **fully resolved** component config, so policies can reason about the real, merged values. See [Custom Policy Validation](/validation/validating) for more.
:::

---

**Next:** everything's in place — bring the whole backend up → **[Deploy Everything →](/quick-start/advanced/provision)**
