# iac

`iac` is a deterministic, serial runbook CLI for infrastructure and operations automation.

Current release: `0.1.0a1` (alpha).

## Core Commands

- `iac init book <name>`
- `iac list books|steps --output table|json|yaml`
- `iac get book <ref> --output table|json|yaml`
- `iac get step <book@step> --output table|json|yaml`
- `iac check book <ref> --output table|json|yaml`
- `iac deps install <ref> [--apply] --output table|json|yaml`
- `iac run cmd <command>`
- `iac run book <ref>`
- `iac run step <book@step>`

Run execution supports:

- one-off command execution with stdin helpers: `--stdin-file`, `--stdin-text`, `--stdin-json`, `--stdin-env`
- command argv mode: `--no-shell` with repeatable `--arg`
- stdout/stderr file management: `--stdout-file`, `--stderr-file`, `--file-mode`
- step selection controls: `--from-step`, `--to-step`, `--only-step`, `--skip-step`, `--tag`
- timeout override: `--timeout`
- retry overrides: `--retries`, `--retry-delay`

## Runbook Schema (v1)

Top-level keys:

- `version`
- `name`
- `title`
- `description`
- `tags`
- `vars`
- `requires`
- `sensitive`
- `hooks`
- `steps`

Step command modes are mutually exclusive:

- `argv` (explicit tokens)
- `shell` (inline shell block/string)
- `script` (resolved script file path)

### Vars

`vars` is the single parameter surface.

Override precedence:

1. `book.vars`
2. `IAC_VARS` (`k=v,k2=v2` or whitespace-separated)
3. `IAC_VAR_*` (example: `IAC_VAR_AWS_REGION=us-east-1` maps to `aws_region`)
4. repeated `--var key=value`

Templating:

- `{{ var_name }}` for vars
- `${ENV_NAME}` for host environment passthrough in any YAML string

Script resolution directories can be configured via:

- `IAC_SCRIPT_DIRS` (preferred)
- `IAC_SCRIPTS_DIRS` (alias)

Defaults include `./scripts`, `./.iac/scripts`, `~/.iac/scripts`, and `.`.

### Sensitive

`sensitive` is a list of var keys. Values for those keys are redacted from command display, console output, artifact logs, and reports.

```yaml
sensitive:
  - api_token
  - aws_secret_access_key
```

### Requires

`requires` declares executable dependencies and optional install hints.

```yaml
requires:
  - name: tofu
    min_version: ">=1.8.0"
    check: "tofu version"
    install:
      darwin: "brew install opentofu"
      ubuntu: "apt-get update && apt-get install -y opentofu"
```

Supported install target keys:
`darwin`, `ubuntu`, `debian`, `redhat`, `rhel`, `fedora`, `alpine`, `arch`, `amzn`, `windows`.

### Failure Policy

Step `on_fail` and hook `on_fail` are both standardized to:

- `halt`: stop execution immediately
- `warn`: continue, emit warning
- `pass`: continue quietly (non-blocking failure)

### Step Execution Controls

Each step can define:

- `timeout` (seconds, `> 0`)
- `retries` (integer, `>= 0`)
- `retry_delay` (seconds, `>= 0`)

`iac run` reports include attempt counts (`ATTEMPTS`) and prints a failure summary with a rerun hint when a hard failure occurs.

## Packaging

`pyproject.toml` is configured for explicit package discovery with:

```toml
[tool.setuptools.packages.find]
include = ["iac*"]
```

This avoids accidental inclusion of `books/` as a Python package.

## PyPI Publishing

This project is configured for release publishing with GitHub Actions in:

- `.github/workflows/publish-pypi.yml`

Release flow:

1. Create/publish a GitHub release.
2. Workflow runs tests, builds sdist/wheel, validates with `twine check`.
3. On release events, package is published to PyPI via trusted publishing.

Prerequisite:

- Configure PyPI trusted publisher for this GitHub repository and workflow in the PyPI project settings.

## Known Limitations (Alpha)

- Coverage gate is enforced at 100% for the alpha-tested scope defined in `pyproject.toml` coverage omit rules.
- `iac run cmd` JSON/YAML output is structured, but command stdout/stderr still stream unless `--quiet` is set.
- Dependency install commands in `requires.install` are advisory; they execute exactly as declared when `iac deps install --apply` is used.
