Terminal
The terminal resource provides an interactive shell session tab that users can use to execute commands in a container or VM. It creates a fully functional terminal emulator in the browser that connects to the target resource.
Use Cases
Section titled “Use Cases”As a lab author, you can use terminal resources to provide command-line access:
- System Administration: Give users shell access to servers, containers, or VMs for configuration and management tasks
- Development Environments: Provide terminals in development containers with pre-installed tools and languages
- Database Management: Create specialized terminals for database CLIs (e.g. psql, mysql, mongo)
- Monitoring and Debugging: Set up terminals with monitoring tools (e.g. htop, top) or debugging utilities
- Multi-Environment Labs: Create multiple terminals for different roles (client, server, database) in complex scenarios
- Kubernetes Labs: Use terminals in kubectl-configured containers for cluster management exercises
Terminals are essential for hands-on learning where users need direct command-line interaction with systems.
HCL Syntax
Section titled “HCL Syntax”Basic Syntax
Section titled “Basic Syntax”resource "terminal" "name" { target = resource.container.ubuntu}
Full Syntax
Section titled “Full Syntax”resource "terminal" "name" { target = resource.container.ubuntu shell = "/bin/bash" user = "root" group = "root" working_directory = "/home/user" command = ["tmux", "new-session"]}
Fields
Section titled “Fields”Field | Required | Type | Description |
---|---|---|---|
target | ✓ | reference to container or vm | Reference to the container or VM to attach the terminal to |
shell | string | Shell program to use for the terminal session. Defaults to “/bin/sh”. | |
user | string | User to run the terminal session as. Defaults to “root”. | |
group | string | Group to run the terminal session as. Defaults to “root”. | |
working_directory | string | Initial working directory for the terminal. Defaults to ”/”. | |
command | list(string) | Command to execute instead of interactive shell |
Hidden/Internal Fields
Section titled “Hidden/Internal Fields”Field | Type | Description |
---|---|---|
prompt |
string | Internal use only |
theme |
string | Internal use only |
Deprecated Fields
Section titled “Deprecated Fields”Field | Type | Description |
---|---|---|
title |
string | DEPRECATED: Use the title field on the tab in your layout instead |
Validation Rules
Section titled “Validation Rules”-
Target limitation: The target can only reference resources of type:
container
vm
Note: Terminal resources cannot currently target
kubernetes_cluster
ornomad_cluster
resources directly. -
Shell validation: The specified shell must exist in the target container/VM
-
User/Group validation: The specified user and group must exist in the target
-
Working directory: The directory must exist or be creatable by the specified user
Default Values
Section titled “Default Values”The following defaults are applied during processing:
Field | Default Value |
---|---|
shell |
"/bin/sh" |
user |
"root" |
group |
"root" |
working_directory |
"/" |
Examples
Section titled “Examples”Basic Terminal
Section titled “Basic Terminal”resource "terminal" "main" { target = resource.container.ubuntu}
Terminal with Bash Shell
Section titled “Terminal with Bash Shell”resource "terminal" "bash_terminal" { target = resource.container.devbox shell = "/bin/bash" user = "developer" group = "developer" working_directory = "/home/developer"}
Terminal with Initial Command
Section titled “Terminal with Initial Command”resource "terminal" "monitoring" { target = resource.container.monitor command = ["htop"]}
Multiple Terminals in Layout
Section titled “Multiple Terminals in Layout”resource "layout" "multi_terminal" { column { width = "30%" instructions {} }
column { width = "35%"
tab "server" { target = resource.terminal.server title = "Server" active = true }
tab "client" { target = resource.terminal.client title = "Client" } }
column { width = "35%"
tab "logs" { target = resource.terminal.logs title = "Logs" } }}
Terminal with Tmux Session
Section titled “Terminal with Tmux Session”resource "terminal" "tmux" { target = resource.container.workspace shell = "/bin/bash" working_directory = "/workspace" command = ["tmux", "new-session", "-s", "main"]}
Terminal for Database CLI
Section titled “Terminal for Database CLI”resource "terminal" "postgres_cli" { target = resource.container.postgres user = "postgres" group = "postgres" command = ["psql", "-d", "mydb"]}
Best Practices
Section titled “Best Practices”- Shell Selection: Use
/bin/bash
for better interactive features, fallback to/bin/sh
for minimal containers - User Configuration: Run terminals as non-root users when possible for security
- Working Directory: Set appropriate starting directories for the lab context
- Multiple Terminals: Use descriptive resource names when creating multiple terminals
- Initial Commands: Use the
command
field for specialized tools (e.g. database CLIs, monitoring tools)
Common Issues
Section titled “Common Issues”-
Shell Not Found: Terminal fails to start with “shell not found” error
- Verify the shell exists in the container:
docker exec <container> which /bin/bash
- Use
/bin/sh
as a fallback for minimal images
- Verify the shell exists in the container:
-
Permission Denied: Terminal cannot access certain directories or files
- Check user/group permissions match the target container’s file ownership
- Ensure the working directory is accessible by the specified user
-
Target Type Error: “target can only be of the following types: container, vm”
- For Kubernetes clusters, create a container with kubectl configured
- Use a jump host or bastion container for cluster access
Kubernetes Cluster Access
Section titled “Kubernetes Cluster Access”To provide terminal access to a Kubernetes cluster:
## Container with kubectl configuredresource "container" "kubectl" { image { name = "bitnami/kubectl:latest" }
volume { source = resource.kubernetes_cluster.k8s.kubeconfig_path destination = "/root/.kube/config" type = "bind" }}
# Terminal accessing the kubectl containerresource "terminal" "k8s_terminal" { target = resource.container.kubectl working_directory = "/root"}