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.

Alternatively, if you have Go installed, you can build from source:

go install github.com/alt-dima/iacconsole-cli@latest

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