# arguments

The `arguments` field declares positional arguments for a custom command. Argument values are available to steps, env, and templates as `{{ .Arguments.<name> }}`.

## Positional Arguments

If a positional argument is required but not provided by the user, the command fails — unless you define a `default`.

For example, this `greet` command accepts one `name` argument and defaults to "John Doe":

```yaml
commands:
  - name: greet
    description: This command says hello to the provided name
    arguments:
      - name: name
        description: Name to greet
        default: John Doe
    steps:
      - "echo Hello {{ .Arguments.name }}!"
```

Run it with an argument:

```shell
atmos greet Alice
```

or rely on the default:

```shell
atmos greet
```

Atmos passes each value through exactly as you typed it. A value can contain commas, be an
empty string, or contain non-ASCII text, and it still maps to its own argument.

## Optional Arguments

An argument that is not `required` and has no `default` can be omitted. Its value is an empty
string in `{{ .Arguments.<name> }}` and in `ctx.arguments` for [script steps](/steps/type/script#reading-command-inputs-in-script-steps),
so a step can test for it without the command failing:

```yaml
commands:
  - name: dump
    description: Dump a service's settings
    arguments:
      - name: service
        description: Service name
        required: true
      - name: region
        description: Region to restrict the dump to
        required: false
    steps:
      - |
        {{ if .Arguments.region }}
        echo "Dumping {{ .Arguments.service }} in {{ .Arguments.region }}"
        {{ else }}
        echo "Dumping {{ .Arguments.service }} in every region"
        {{ end }}
```

```shell
atmos dump api              # region is ""
atmos dump api us-east-1    # region is "us-east-1"
```

Optional arguments follow the required ones, because arguments are matched by position. An
omitted argument that has a `default` takes that default instead.

Arguments after `--` belong to `{{ .TrailingArgs }}`. They do not fill omitted positional
arguments or replace their defaults, and they are not exposed through `ctx.arguments`.

- **`name`** — Required. Argument name, referenced as `{{ .Arguments.<name> }}`.
- **`description`** — Help text shown in `atmos help`. The command usage line shows required arguments as `<required>` and optional arguments as `[optional]`.
- **`required`** — When `true`, the command fails if the argument is omitted and no `default` is set. When `false` (the default), an omitted argument without a `default` is an empty string. See [Optional Arguments](#optional-arguments).
- **`default`** — Value used when the argument is omitted.
- **`type`** — Optional semantic type: `component` or `stack`. See [Typed Arguments](#typed-arguments).
- **`values`** — Optional list of allowed string values. Works exactly like [`values` on flags](/cli/configuration/commands/flags#restricting-values) — a value outside the list is rejected, and a missing `required` argument with `values` set prompts with a picker in an interactive terminal.

## Trailing Arguments

Atmos supports **trailing arguments** after `--` (a standalone double-dash). The `--` is a delimiter that signals the end of Atmos-specific options. Anything after `--` is passed directly to the underlying command without being interpreted by Atmos, and is available in `{{ .TrailingArgs }}`.

```yaml
commands:
  - name: ansible run
    description: "Runs an Ansible playbook, allowing extra arguments after --."
    arguments:
      - name: playbook
        description: "The Ansible playbook to run"
        default: site.yml
        required: true
    steps:
      - "ansible-playbook {{ .Arguments.playbook }} {{ .TrailingArgs }}"
```

Output:

```bash
$ atmos ansible run -- --limit web
Running: ansible-playbook site.yml --limit web

PLAY [web] *********************************************************************
```

## Typed Arguments

Set `provides: component` or `provides: stack` to tell Atmos that an argument provides the
component name or stack name. Atmos then resolves the matching component configuration and
exposes it as `{{ .Component.* }}`. See [`component`](/cli/configuration/commands/component) for
the full custom component type workflow.

```yaml
commands:
  - name: script
    description: "Run script components"
    arguments:
      - name: component
        description: "Component name"
        provides: component          # this argument provides the component name
        required: true
    component:
      type: script
    steps:
      - 'echo "Running {{ .Component.component }} in {{ .Component.atmos_stack }}"'
```

The same `provides:` field works on flags too — see
[`provides`](/cli/configuration/commands/flags#provides).

Deprecated: `type: component` / `type: stack`

Older configs may still use `type: component` or `type: stack` on arguments. This still works but
is deprecated in favor of `provides:`, which uses the same field name on both arguments and flags.
