Skip to main content

Configure Command Override

The command setting allows you to override the executable that Atmos uses to run Terraform, Helmfile, or Packer commands. This is useful for using alternative tools like OpenTofu, custom wrappers, or specific binary versions.

Use Cases

  • OpenTofu: Use tofu instead of terraform for your infrastructure.
  • Custom Wrappers: Use wrapper scripts that add logging, timing, or other functionality.
  • Version Management: Point to specific binary versions managed by tools like tfenv or asdf.
  • Testing: Use mock binaries during testing or development.

Configuration Scopes

The command setting can be defined at two levels:

Component-Type Level

Set the command for all components of a type:

# stacks/orgs/acme/_defaults.yaml
terraform:
command: tofu

helmfile:
command: /usr/local/bin/helmfile

Component Level

Override the command for a specific component:

components:
terraform:
legacy-module:
command: terraform # Use terraform instead of tofu for this component
vars:
# ...

Examples

Using OpenTofu

stacks/orgs/acme/_defaults.yaml

terraform:
command: tofu

All Terraform components will now use tofu instead of terraform.

Using Version Manager Shims

stacks/orgs/acme/_defaults.yaml

terraform:
command: /Users/me/.asdf/shims/terraform

Custom Wrapper Script

stacks/orgs/acme/_defaults.yaml

terraform:
command: /opt/scripts/terraform-wrapper.sh

Example wrapper script:

#!/bin/bash
# /opt/scripts/terraform-wrapper.sh

# Log command execution
echo "[$(date)] Running: terraform $@" >> /var/log/terraform.log

# Execute terraform with timing
time terraform "$@"
exit_code=$?

# Log completion
echo "[$(date)] Completed with exit code: $exit_code" >> /var/log/terraform.log

exit $exit_code

Mixed Tool Usage

Use different tools for different components:

stacks/orgs/acme/_defaults.yaml

# Default to OpenTofu
terraform:
command: tofu

stacks/orgs/acme/plat/prod/us-east-1.yaml

components:
terraform:
# Most components use tofu (inherited default)
vpc:
vars:
vpc_cidr: "10.0.0.0/16"

# This component requires terraform for a specific provider
legacy-provider:
command: terraform
vars:
# ...

Environment-Specific Commands

stacks/orgs/acme/plat/dev/_defaults.yaml

terraform:
command: terraform # Use standard terraform in dev

stacks/orgs/acme/plat/prod/_defaults.yaml

terraform:
command: /opt/terraform/1.5.7/terraform # Use pinned version in prod

Helmfile Command Override

stacks/orgs/acme/_defaults.yaml

helmfile:
command: /usr/local/bin/helmfile-0.150.0

Packer Command Override

stacks/orgs/acme/_defaults.yaml

packer:
command: /opt/hashicorp/packer/1.9.0/packer

Precedence

The command is resolved in this order:

  1. Component level (components.terraform.<name>.command)
  2. Component-type level (terraform.command)
  3. Default (the tool name itself: terraform, helmfile, or packer)

Best Practices

  1. Use Absolute Paths: When specifying custom binaries, use absolute paths to avoid PATH-related issues.

  2. Version Pin in Production: Consider pinning specific versions in production environments for reproducibility.

  3. Test Wrapper Scripts: Ensure wrapper scripts properly pass through all arguments and return exit codes correctly.

  4. Document Tool Requirements: If using non-standard tools like OpenTofu, document this requirement for your team.

  5. Use Component-Type Defaults: Set the command at the terraform: level rather than on each component to maintain consistency.

Compatibility Notes

OpenTofu

OpenTofu is a drop-in replacement for Terraform. When using command: tofu:

  • All atmos terraform commands work the same way
  • State files are compatible (OpenTofu uses the same state format)
  • Most providers work without modification

Terraform vs Tofu Feature Differences

Some features may differ between Terraform and OpenTofu. Refer to their respective documentation for compatibility details.