Skip to main content

Tutorial: Your First Workflow

This tutorial explains the steps for users to create and execute their first workflow using actor-IaC. Users will learn from creating an empty directory to executing a workflow that displays "Hello World" on the local machine.

Prerequisites

Users must satisfy the following conditions:

  • actor-IaC is installed on the user's machine (see installation tutorial for installation instructions)
  • Java 21 or higher is installed on the user's machine
  • JBang is installed on the user's machine

1. Create a Working Directory

Users create an empty directory to place workflow files.

mkdir -p ~/works/testcluster-iac
cd ~/works/testcluster-iac

Executing the cd command is not mandatory, but setting ~/works/testcluster-iac as the current directory allows users to use relative paths in subsequent commands, which is convenient. This tutorial proceeds with explanations assuming the user has moved to the working directory.

When users execute the ls command, they can confirm that the ~/works/testcluster-iac directory is empty.

$ ls -la
total 0
drwxr-xr-x 2 user user 40 Jan 14 10:00 .
drwxr-xr-x 3 user user 60 Jan 14 10:00 ..

2. Place the Launcher Script

Users place the JBang launcher script actor_iac.java for executing actor-IaC in the ~/works/testcluster-iac directory. The actor_iac.java file is provided in the root directory of the actor-IaC repository, so users copy it from the actor-IaC repository to the ~/works/testcluster-iac directory.

cp /path/to/actor-IaC/actor_iac.java .
chmod +x actor_iac.java
note

Users need to replace /path/to/actor-IaC/ with the actual path to the actor-IaC repository. The actor_iac.java script detects and executes the JAR file from the Maven local repository (~/.m2/repository/com/scivicslab/actor-IaC/VERSION/actor-IaC-VERSION.jar). When users execute the mvn install command in the actor-IaC repository, Maven installs the JAR file to the Maven local repository. Users can also explicitly specify the JAR file path using the environment variable ACTOR_IAC_JAR.

3. Create the inventory.ini File (For Local Execution)

The inventory.ini file defines the target nodes where actor-IaC executes workflows. As a first example, users create a simple configuration targeting only the local machine in the ~/works/testcluster-iac/inventory.ini file.

cat > inventory.ini << 'EOF'
[local]
localhost actoriac_connection=local
EOF

The meanings of the configuration contents in the ~/works/testcluster-iac/inventory.ini file are as follows:

  • [local] — Users define a group name
  • localhost — Users define a host name
  • actoriac_connection=local — actor-IaC uses local execution instead of SSH connection
note

actor-IaC recommends variable names in the actoriac_* format, but the ansible_* format can also be used for Ansible compatibility. Users can use the following variables:

actor-IaC formatAnsible-compatible formatDescription
actoriac_connectionansible_connectionConnection method (local or ssh)
actoriac_hostansible_hostActual connection target hostname/IP
actoriac_useransible_userSSH username
actoriac_portansible_portSSH port number

When users specify both formats, actor-IaC prioritizes the actoriac_* format.

4. Understand the Actor Tree Generated by actor-IaC

When actor-IaC reads the ~/works/testcluster-iac/inventory.ini file and executes a workflow, actor-IaC generates the following actor tree.

ROOT actor
├── logStore actor
└── nodeGroup actor
├── accumulator actor
└── node-localhost actor

For users to effectively use actor-IaC, it is important to understand what kind of actor tree actor-IaC generates internally. The actor tree generated by actor-IaC has three important design points.

4.1 Parent-Child Relationship Between nodeGroup Actor and node Actors

The purpose of actor-IaC is to execute the same configuration tasks on multiple servers in parallel. To achieve parallel execution, actor-IaC places multiple node actors as child actors under the nodeGroup actor.

actor-IaC places the node-localhost actor as a child actor of the nodeGroup actor. Both the nodeGroup actor and node-localhost actor are actors that contain an Interpreter for executing YAML-format workflows.

  • nodeGroup actor: actor-IaC executes the main workflow on the nodeGroup actor. The main workflow controls which sub-workflows to execute on which nodes.
  • node-localhost actor: actor-IaC executes sub-workflows on the node-localhost actor. Sub-workflows define the specific commands to execute on each node.

When users define 3 servers in the ~/works/testcluster-iac/inventory.ini file, actor-IaC generates the following actor tree:

ROOT actor
├── logStore actor
└── nodeGroup actor
├── accumulator actor
├── node-server1 actor
├── node-server2 actor
└── node-server3 actor

actor-IaC executes the same sub-workflow in parallel on the node-server1 actor, node-server2 actor, and node-server3 actor.

4.2 Log Output Aggregation by the accumulator Actor

When multiple node actors execute sub-workflows in parallel, multiple node actors generate log output simultaneously. Without aggregating log output, users cannot determine which log came from which node.

The accumulator actor exists to aggregate log output from multiple node actors in one place. Multiple node actors send log output to the accumulator actor. The accumulator actor distributes received log output to the following two destinations:

  • Output to standard output (console)
  • Sending to the logStore actor (for persistence)

By going through the accumulator actor, actor-IaC centrally manages the execution results of all node actors executed in parallel.

4.3 Log Persistence by the logStore Actor

In the actor model, processing within individual actors is executed sequentially. Since actors process only one message at a time, there is no need to consider parallel processing inside actors. actor-IaC leverages this property of the actor model for writing to databases and files.

The logStore actor is dedicated to log persistence. actor-IaC creates a dedicated managedThreadPool (single thread) for the logStore actor, and the logStore actor operates on this thread pool. Even if multiple node actors send logs to the logStore actor, the logStore actor processes received messages one by one in order. The logStore actor writes logs to the following two destinations:

  • ~/works/testcluster-iac/actor-iac-logs.mv.db file (H2 database)
  • ~/works/testcluster-iac/actor-iac-YYYYMMDDHHmm.log file (text log)

By going through the logStore actor, actor-IaC naturally serializes writes to files and databases. Logs from multiple node actors are written in mixed order of arrival, but since each log entry includes nodeId, users can filter by nodeId later to extract logs for specific nodes.

The division of roles between the accumulator actor and logStore actor is as follows:

ActorRolePurpose
accumulator actorLog collection and distributionAggregate logs executed in parallel in one place
logStore actorLog persistenceSerialize writes by leveraging actor model properties
node-server1 actor ──┐
node-server2 actor ──┼─→ accumulator actor ─→ logStore actor ─→ actor-iac-logs.mv.db (H2 database)
node-server3 actor ──┘ │ └─→ actor-iac-YYYYMMDDHHmm.log (text log)

└─→ standard output (console)

5. Create the Hello World Workflow

Users create a directory to place workflow files and create the first workflow.

mkdir -p hello

When users execute the tree command, the structure of the ~/works/testcluster-iac directory is as follows.

$ tree
.
├── actor_iac.java
├── hello
└── inventory.ini

5.1 Create the Sub-Workflow

Users create the sub-workflow to be executed on each node in the ~/works/testcluster-iac/hello/hello.yaml file.

cat > hello/hello.yaml << 'EOF'
name: hello
steps:
- states: ["0", "end"]
actions:
- actor: this
method: executeCommand
arguments:
- "echo 'Hello from actor-IaC!'"
EOF

The ~/works/testcluster-iac/hello/hello.yaml file defines the workflow name hello. When actor-IaC executes the workflow, actor-IaC sets the current state to 0. actor-IaC calls the executeCommand method of this (the current node actor itself) and executes the echo 'Hello from actor-IaC!' command. When the executeCommand method execution succeeds, actor-IaC transitions the current state from 0 to end. When the current state becomes end, actor-IaC terminates the workflow execution.

About actor: this

In sub-workflows, actor: this is used to reference the current actor itself. Since sub-workflows are executed on each node actor, actor: this refers to the executing node actor (e.g., node-localhost). Note that while main workflows use actor: nodeGroup to reference the nodeGroup actor, sub-workflows use actor: this.

5.2 Create the Main Workflow

Users create the main workflow that calls the sub-workflow in the ~/works/testcluster-iac/hello/main-hello.yaml file.

cat > hello/main-hello.yaml << 'EOF'
name: main-hello
steps:
- states: ["0", "end"]
actions:
- actor: nodeGroup
method: apply
arguments:
actor: "node-*"
method: runWorkflow
arguments: ["hello.yaml"]
EOF

The ~/works/testcluster-iac/hello/main-hello.yaml file defines the workflow name main-hello. When actor-IaC executes the workflow, actor-IaC calls the apply method of the nodeGroup actor. The apply method executes runWorkflow("hello.yaml") on all node actors matching node-*.

note

When users specify the -g local option on the command line, actor-IaC automatically creates node actors before workflow execution. There is no need to explicitly create node actors in the main workflow.

6. Verify the Directory Structure

When users complete the work up to this point, the ~/works/testcluster-iac directory has the following structure.

$ tree ~/works/testcluster-iac
.
├── actor_iac.java
├── hello
│ ├── hello.yaml
│ └── main-hello.yaml
└── inventory.ini

7. Execute the Workflow

7.1 Check the Workflow List

Users execute the list command to check the workflows in the ~/works/testcluster-iac/hello directory.

./actor_iac.java list -d ./hello

actor-IaC displays the following output:

Available workflows (directory: ./hello)
------------------------------------------------------------------------------------------
# File (-w) Path Workflow Name (in logs)
------------------------------------------------------------------------------------------
1 hello ./hello/hello.yaml hello
2 main-hello ./hello/main-hello.yaml main-hello

7.2 Execute the Workflow

Users execute the run command to execute the main workflow.

./actor_iac.java run -d ./hello -w main-hello -i inventory.ini -g local

The explanations for each option are as follows:

OptionDescription
-d ./helloUsers specify the workflow directory
-w main-helloUsers specify the workflow name to execute
-i inventory.iniUsers specify the inventory file
-g localUsers specify the target group

actor-IaC displays each step of the workflow in cowsay-format ASCII art and outputs Hello from actor-IaC! at the end. The detailed output format is explained in the next section.

8. Verify the Execution Results

When actor-IaC executes a workflow, actor-IaC outputs the execution results to the console. actor-IaC displays each step of the workflow in cowsay-format ASCII art.

$ ./actor_iac.java run -d ./hello -w main-hello -i inventory.ini -g local
2026-01-15 03:33:24 INFO Loading workflow: main-hello.yaml
2026-01-15 03:33:24 INFO Creating node actors for group: local
2026-01-15 03:33:24 INFO Created 1 node actors for group 'local'
2026-01-15 03:33:24 INFO Starting workflow execution...
____________________________
/ [main-hello] \
| - states: ["0", "end"] |
| actions: |
| - actor: nodeGroup |
| method: apply |
\ arguments: {...} (3 keys) /
----------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||

2026-01-15 03:33:24 INFO Applying method 'runWorkflow' to 1 actors matching 'node-*'
_______________________________
/ [hello] \
| - states: ["0", "end"] |
| actions: |
| - actor: this |
| method: executeCommand |
| arguments: ["echo 'Hello from |
\ actor-IaC!'"] /
-------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||

Hello from actor-IaC!
2026-01-15 03:33:24 INFO Workflow completed successfully: Workflow completed

The console output includes the following information:

  • Log messages (with timestamps)
  • Cowsay-format workflow step display (workflow name, states, actions)
  • Command execution results (Hello from actor-IaC!)
  • Workflow completion message

actor-IaC visually separates each step of the workflow, making it easy for users to understand the workflow progress.

note

actor-IaC saves execution logs to an H2 database (actor-iac-logs.mv.db in the current directory). Specifying the -l option also enables text file log output. How to utilize the log database is explained in tutorials covering more complex workflows.

9. Final Directory Structure

After actor-IaC executes the workflow, the ~/works/testcluster-iac directory has the following structure.

~/works/testcluster-iac/
├── actor_iac.java
├── actor-iac-logs.mv.db # Log database automatically generated by actor-IaC
├── hello
│ ├── hello.yaml
│ └── main-hello.yaml
└── inventory.ini