CLI Guide (Open Source & Free Forever)

The free, open-source engine of the IaC Console tool suite.

The iacconsole-cli is a powerful wrapper around OpenTofu/Terraform that handles the complexity of injecting variables from the CMDB inventory and managing state backends seamlessly. It’s completely open-source and free to use—even without a paid IaC Console account.

Part of the Complete Tool Suite

The CLI is one of four integrated components:

  1. iacconsole-cli — Local Terraform/OpenTofu execution (you are here)
  2. iacconsole-api & CMDB — Configuration management database
  3. IaC Console Web App — Browser-based management interface
  4. go-entrypoint — Runtime config/secrets injection for microservices

Open Source: View the source code and contribute on GitHub.

Why Use the CLI?

For Individual Engineers

  • Free forever — No vendor lock-in, open-source core functionality
  • Local execution — Your AWS/Azure/GCP credentials never leave your machine
  • Standalone mode — Works with local JSON files, no API required
  • DRY infrastructure — Write Terraform once, deploy to multiple environments

For Teams (With IaC Console Account)

  • Secure Agent Mode — Connect browser UI to local execution
  • CMDB integration — Centralized configuration management
  • AI Assistant — Generate and review code with AI
  • Audit trails — Track who changed what, when, and why
  • Team collaboration — Shared visibility and governance

Important for Engineers: If you find the CLI valuable, advocate to your CTO/Engineering Manager for a team account. The ROI for 1-5 engineer teams justifies itself quickly by eliminating the need to build and maintain internal IaC tooling.

Installation

Download the latest pre-built binary for your platform (Linux/macOS) from GitHub Releases.

Agent Mode

The Agent Mode allows you to trigger deployments directly from the IaCConsole Web Dashboard while executing locally on your machine.

  1. Set your API credentials (required):
export IACCONSOLE_API_URL='https://accountid:password@api.iacconsole.com'

⚠️ The IACCONSOLE_API_URL environment variable is required. If not set, you will see: Configuration error: IACCONSOLE_API_URL is empty

  1. Start the agent:
iacconsole-cli agent

By default, the agent will prompt for confirmation before executing each command. To automatically approve and execute commands without prompting, use the --auto-execute flag:

iacconsole-cli agent --auto-execute

Local Mode

You can also use the CLI in standalone mode with local JSON files as your inventory by setting the inventory_path in your .iacconsolerc or using flags.

Core Commands

  • iacconsole-cli init: Initializes a new working directory with a default structure and .iacconsolerc file.
  • iacconsole-cli exec -o org -u unit -d dim:val -- plan: Executes a plan by synthesizing your code and configuration in a temporary environment.
  • iacconsole-cli exec -o org -u unit -d dim:val -- apply: Applies changes to your infrastructure using the synthesized environment.

Init Command Options

  • --target-dir / -d: Target directory (defaults to current)
  • --force / -f: Force overwrite of existing .iacconsolerc file
  • --with-example / -e: Create example organization structure (default: true)

Exec Command Flags

  • -o, --org: Organization name (required)
  • -u, --unit: Infrastructure unit name (required)
  • -d, --dimension: Dimensions (can be specified multiple times, e.g., -d env:prod -d region:us-east-1)
  • -w, --workspace: Workspace for IaCConsole DB (default: “master”)
  • -c, --clean: Remove temporary directory after execution
  • -v, --verbose: Enable verbose output (global flag)

Environment Variables as Terraform Vars

Any environment variable prefixed with iacconsole_envvar_ will be automatically passed as a Terraform variable:

export iacconsole_envvar_my_var="some_value"

In your Terraform code, this becomes available as var.iacconsole_envvar_my_var

How Inventory Data is Injected

The CLI automatically generates Terraform variables from your inventory dimensions. You do NOT need to manually define these variables - both the variable definitions and values are automatically created in the temporary execution directory.

For each dimension specified with -d dimkey:dimvalue, the following variables are created:

  • var.iacconsole_{dimkey}_data: The complete JSON object from the inventory for this dimension
  • var.iacconsole_{dimkey}_name: The dimension value name (e.g., “prod”, “local”)
  • var.iacconsole_{dimkey}_defaults: (Optional) Default values if dim_defaults exists in inventory

How it works:

  1. The CLI generates iacconsole_*_vars.tf.json files with variable definitions
  2. The CLI generates iacconsole_*.auto.tfvars.json files with actual values
  3. You simply use the variables directly in your Terraform code

Example usage in Terraform:

# Command: iacconsole-cli exec -o myorg -u vpc -d env:prod -d datacenter:us-east

# In your Terraform code (NO variable definitions needed!):
resource "aws_vpc" "main" {
  cidr_block = var.iacconsole_env_data.vpc_cidr

  tags = {
    Environment = var.iacconsole_env_name  # "prod"
    Datacenter  = var.iacconsole_datacenter_name  # "us-east"
  }
}

output "az_count" {
  value = var.iacconsole_datacenter_data.az_count
}

Note: Do not create variables.tf with definitions for iacconsole_* variables - the CLI handles this automatically!

Example:

iacconsole-cli exec -o demo-org -d env:local -u vpc -- plan

Unit Structure

Each infrastructure unit must be organized in a directory structure with a required unit_manifest.json file that defines which dimensions are needed for that unit.

Directory Layout

units/
└── myorg/
    └── vpc/
        ├── unit_manifest.json  # Required
        ├── main.tf
        ├── variables.tf        # Optional - only for your custom variables
        └── outputs.tf

Note: The variables.tf file is shown here but is optional. You only need it for your own custom variables (like provider configurations). Do not define iacconsole_* variables there - the CLI generates those automatically.

unit_manifest.json

This file defines which dimensions are required for the unit. These dimensions are used for:

  • Generating the state file path
  • Validating that required dimensions are provided
  • Determining which inventory data to fetch

Example manifest:

{
  "dimensions": ["env", "region"]
}

For this unit, you must specify both env and region dimensions when executing:

iacconsole-cli exec -o myorg -u vpc -d env:prod -d region:us-east-1 -- plan

Note: The order of dimensions in unit_manifest.json affects the generated state file path: org_myorg/env_prod/region_us-east-1/vpc.tfstate

Units vs. Shared Modules

Understanding the difference between Units and Shared Modules is crucial:

Units (What You Deploy)

  • Complete deployable configurations for specific infrastructure purposes
  • Located in units/[org-name]/[unit-name]/
  • Each unit requires a unit_manifest.json defining its dimensions
  • Examples: vpc, microservice-app, database-cluster, monitoring
  • Executed directly via: iacconsole-cli exec -o org -u unit-name -d dimension:value -- plan

Shared Modules (Building Blocks)

  • Reusable Terraform code that multiple units can use
  • Located in shared-modules/[module-name]/
  • Generic components like S3 buckets, IAM roles, security groups
  • Automatically linked to every unit’s execution directory by the CLI
  • Never executed directly - always called from within units

How Shared Modules Work

The shared modules path is fully configurable in .iacconsolerc:

defaults:
  units_path: examples/units
  shared_modules_path: examples/shared-modules # ← Change this to your path
  inventory_path: examples/inventory

When you run a unit, the CLI automatically links/mounts the configured shared-modules/ folder into every unit’s temporary execution directory, making all modules available:

# In any unit's main.tf - ALWAYS use "./shared-modules/" path
module "s3_bucket" {
  source      = "./shared-modules/s3-bucket"  # ✅ Correct!
  bucket_name = "my-bucket-${var.iacconsole_env_name}"
}

# This works even though the actual folder might be elsewhere on disk
# The CLI handles the linking automatically

Important: Always use ./shared-modules/ in your module source paths, never ../../shared-modules/. The CLI mounts the folder, so the path is always relative to the unit’s execution directory.

Organizing Modules with Subdirectories

For complex projects, organize modules into subdirectories:

shared-modules/
├── networking/
│   ├── vpc/
│   ├── subnet/
│   └── nat-gateway/
├── security/
│   ├── iam-role/
│   ├── security-group/
│   └── kms-key/
└── storage/
    ├── s3-bucket/
    └── ebs-volume/

Reference them with subdirectory paths:

module "vpc" {
  source = "./shared-modules/networking/vpc"
  cidr   = var.iacconsole_datacenter_data.vpc_cidr
}

module "iam_role" {
  source    = "./shared-modules/security/iam-role"
  role_name = "app-role"
}
  bucket_name = "my-bucket-${var.iacconsole_env_name}"
}

Real-World Example

Shared Module: S3 bucket with encryption and policies

shared-modules/
└── s3-bucket/
    ├── main.tf         # S3 bucket resource, policy, encryption
    ├── variables.tf    # Accepts: bucket_name, custom_policy, versioning
    └── outputs.tf      # Outputs: bucket_arn, bucket_name

Unit 1: VPC with flow logs

# units/myorg/vpc/main.tf
module "flow_logs" {
  source      = "./shared-modules/s3-bucket"
  bucket_name = "vpc-flow-logs-${var.iacconsole_env_name}"
}

resource "aws_vpc" "main" {
  cidr_block = var.iacconsole_datacenter_data.vpc_cidr
}

resource "aws_flow_log" "main" {
  log_destination = module.flow_logs.bucket_arn
  vpc_id          = aws_vpc.main.id
}

Unit 2: Microservice with S3 storage

# units/myorg/microservice/main.tf
module "app_storage" {
  source      = "./shared-modules/s3-bucket"
  bucket_name = "app-data-${var.iacconsole_env_name}"
}

Benefits:

  • Write S3 configuration logic once in the shared module
  • Reuse across all units (VPC, microservices, databases, etc.)
  • Update S3 best practices in one place
  • CLI handles all linking automatically

Configuration File (.iacconsolerc)

The CLI reads configuration from .iacconsolerc file in YAML format. The file is searched in the following order:

  • Current working directory
  • User’s home directory ($HOME/.iacconsolerc)
  • Custom path via --config flag

Configuration Options

Example configuration file created by iacconsole-cli init:

defaults:
  units_path: examples/units
  inventory_path: examples/inventory
  cmd_to_exec: tofu
# shared_modules_path: examples/shared-modules
# backend:
#   bucket: my-tfstates
#   key: $iacconsole_state_path
#   region: us-east-1

# Organization-specific overrides:
# example-org:
#   backend:
#     bucket: example-org-tfstates

The backend section is used to configure your remote state storage. IaCConsole CLI replaces $iacconsole_state_path at runtime with a unique path derived from your org, dimensions, and unit name — no manual state key management required.

Full Terraform State Management guide →