# components.get

The `components.get` function resolves a component in a stack and returns a handle with its identity, directory,
and fully resolved configuration. The configuration goes through the same inheritance, templating, and YAML-function
pipeline as any other Atmos command and is read-only in the script.

## Usage

```python
components.get(name, stack, type)
```

## Arguments

- **`name`** — Required. The component name as it appears in the stack, which can differ from the directory that holds its code.
- **`stack`** — Required. The stack name.
- **`type`** — Required. The component type, for example `"terraform"`, `"helmfile"`, `"packer"`, `"ansible"`,
  `"container"`, or the name of a custom component type.

All three arguments are required, can be passed by keyword, and must be non-empty. Pass the stack explicitly in
workflows and hooks. In a custom command that declares a `component:`, [`ctx.component`](/functions/automation/ctx.component)
already holds that command's component.

## Returns

A component handle with these read-only attributes:

- **`name`, `stack`, `type`** — The identity of the component instance, as strings.
- **`implementation`** — The component's implementation, such as the name of the directory that holds its code. It can differ from `name` when components inherit shared code.
- **`path`** — The absolute path of the component's working directory.
- **`vars`, `settings`, `metadata`** — The matching sections of the resolved configuration, as dictionaries. A section the component does not define is an empty dictionary.
- **`env`** — The component's `env` section as a dictionary of strings.
- **`config`** — The complete resolved configuration, including sections such as `backend`, `providers`, `hooks`, and `workspace`.
- **`exec`** — A function that runs a program in the component's directory. See [`component.exec`](/functions/automation/component.exec).

Printing a handle shows `component(name = "...", stack = "...", type = "...")` instead of the whole configuration.

The configuration is a snapshot of the stack as Atmos resolved it, so it reflects YAML functions such as `!terraform.output`
and `!env`. Atmos resolves each distinct `(name, stack, type)` once per run and reuses the result, including across parallel
tasks. A failed lookup is not cached, so a later call can retry it.

## Errors

- A missing or empty argument fails with an argument error.
- A component or stack that does not exist fails with the same message the CLI shows, such as
  `Could not find the component ... in the stack ...`.
- A script runs the lookup with its own invocation deadline. To bound a lookup with a task timeout, call
  `components.get` inside the task, with explicit name, stack, and type, instead of reading `ctx.component` there.

## Examples

### Read a component's variables

```python
station = components.get("station", "dev", "terraform")
print(station.vars["location"])   # Stockholm
print(station.metadata["component"])   # weather
```

### Read settings with a default

```python
vpc = components.get(name = "vpc", stack = "prod", type = "terraform")
retention = vpc.settings.get("log_retention_days", 30)
```

### Compare a component across stacks

```python
def region_of(stack):
    return components.get("vpc", stack, "terraform").vars.get("region", "unset")

output = steps.parallel(
    tasks = [steps.task(name = s, function = region_of, args = [s]) for s in ["dev", "staging", "prod"]],
)
```

### Run a command in a component

```python
peer = components.get("api", "dev", "container")
peer.exec(["./smoke-test"])
```

## Related

- [`component.exec`](/functions/automation/component.exec) runs a program in the component's directory.
- [`ctx.component`](/functions/automation/ctx.component) is the component already in scope for a command or hook.
- [`atmos.terraform`](/functions/automation/atmos.terraform) runs Terraform for a component.
- [Atmos Automation Language](/scripting/language) and the [script step](/steps/type/script#custom-components)
