Resource
The resource is the fundamental building block of HCL configuration. Resources represent infrastructure components, services, and other entities that make up your lab environment. Each resource has a specific type (e.g., container
, network
, template
) and defines the desired state for that component.
Use Cases
Section titled “Use Cases”As a lab author, you use resources to build complete lab environments:
- Infrastructure Components: Define containers, networks, and storage volumes that form your lab’s foundation
- Service Configuration: Configure databases, web servers, APIs, and other services needed for hands-on exercises
- User Interface Elements: Create terminals, editors, services, and external websites that users interact with
- Content and Tasks: Define pages, tasks, quizzes, and other instructional content that guide users through the lab
- Utility Operations: Use exec, template, and file resources to configure systems and prepare lab environments
- Cloud Integrations: Provision cloud resources like AWS accounts, Azure subscriptions, or Google Cloud projects
Resources work together to create comprehensive, interactive learning environments where users can practice real-world skills.
HCL Syntax
Section titled “HCL Syntax”Basic Syntax
Section titled “Basic Syntax”resource "resource_type" "name" { # Configuration fields specific to resource type}
Full Syntax
Section titled “Full Syntax”resource "container" "web_server" { # Resource-specific configuration image { name = "nginx:latest" }
container_name = "web-server"
port { local = 8080 remote = 80 }
# Common resource fields (available on all resources) depends_on = ["resource.network.main"] disabled = false}
Common Resource Fields
Section titled “Common Resource Fields”All resources inherit these fields from the base resource type:
Field | Required | Type | Description |
---|---|---|---|
depends_ | list(string) | List of resources this resource depends on (delays creation until dependencies are ready) | |
disabled | bool | Whether this resource is disabled and should be skipped during processing. Defaults to false. |
Resource Metadata
Section titled “Resource Metadata”Every resource automatically gets metadata fields that can be referenced:
Field | Type | Description |
---|---|---|
meta.id |
string | Unique identifier for the resource |
meta.name |
string | Resource name (the label you specified) |
meta.type |
string | Resource type (e.g., "container", "network") |
meta.status |
string | Current status of the resource (e.g., "running", "stopped") |
Resource Types
Section titled “Resource Types”Resources are organized into categories based on their functionality:
Infrastructure Resources
Section titled “Infrastructure Resources”Resource Type | Purpose | Reference |
---|---|---|
container |
Docker containers for applications and services | Container Reference |
network |
Isolated networks for container communication | Network Reference |
ingress |
Network ingress rules and load balancing | Ingress Reference |
volume |
Persistent storage volumes | Volume Reference |
Orchestration Resources
Section titled “Orchestration Resources”Resource Type | Purpose | Reference |
---|---|---|
kubernetes_cluster |
Kubernetes clusters for container orchestration | Kubernetes Cluster Reference |
nomad_cluster |
Nomad clusters for workload orchestration | Nomad Cluster Reference |
User Interface Resources
Section titled “User Interface Resources”Resource Type | Purpose | Reference |
---|---|---|
terminal |
Interactive terminal sessions | Terminal Reference |
editor |
Code editors with syntax highlighting | Editor Reference |
service |
Web services and applications | Service Reference |
external_website |
External web resources and documentation | External Website Reference |
Content Resources
Section titled “Content Resources”Resource Type | Purpose | Reference |
---|---|---|
lab |
Lab configuration and metadata | Lab Reference |
page |
Instruction pages with markdown content | Page Reference |
task |
Interactive tasks with validation | Task Reference |
note |
Contextual notes and hints | Note Reference |
quiz |
Knowledge assessment quizzes | Quiz Reference |
Utility Resources
Section titled “Utility Resources”Resource Type | Purpose | Reference |
---|---|---|
exec |
Execute commands and scripts | Exec Reference |
template |
Generate files from templates | Template Reference |
http |
HTTP requests and API interactions | HTTP Reference |
terraform |
Terraform infrastructure provisioning | Terraform Reference |
Resource References
Section titled “Resource References”Resources are referenced using the format:
resource.resource_type.resource_name
Examples of Resource References
Section titled “Examples of Resource References”# Reference a container's nameresource.container.web.meta.name
# Reference a network's IDresource.network.backend.meta.id
# Reference a service's URLresource.service.api.url
# Reference computed attributesresource.kubernetes_cluster.main.kubeconfig_path
Examples
Section titled “Examples”Basic Resource Definition
Section titled “Basic Resource Definition”resource "container" "database" { image { name = "postgres:13" }
container_name = "postgres-db"
environment = { POSTGRES_DB = "myapp" POSTGRES_USER = "admin" POSTGRES_PASSWORD = "password" }
port { local = 5432 remote = 5432 }}
Resource with Dependencies
Section titled “Resource with Dependencies”resource "network" "backend" { subnet = "10.0.1.0/24"}
resource "container" "app" { depends_on = ["resource.network.backend"]
image { name = "myapp:latest" }
network { id = resource.network.backend.meta.id }}
Resource with Cross-References
Section titled “Resource with Cross-References”resource "container" "web" { image { name = "nginx:latest" }
container_name = "web-server"
port { local = 8080 remote = 80 }}
resource "service" "web_ui" { target = resource.container.web port = 8080
title = "Web Application"}
Conditional Resource
Section titled “Conditional Resource”resource "container" "debug_tools" { disabled = !variable.debug_enabled
image { name = "busybox:latest" }
container_name = "debug-container"}
Resource with Complex Configuration
Section titled “Resource with Complex Configuration”resource "kubernetes_cluster" "main" { network { id = resource.network.k8s.meta.id }
node "server" { cpu = 2048 memory = 4096 node_role = "control-plane" }
node "worker" { cpu = 1024 memory = 2048 node_role = "worker" }
config { api_server_port = 6443 service_cidr = "10.96.0.0/12" pod_cidr = "10.244.0.0/16" }}
Resource Chain Example
Section titled “Resource Chain Example”# 1. Create networkresource "network" "lab_network" { subnet = "10.0.0.0/16"}
# 2. Create database containerresource "container" "database" { depends_on = ["resource.network.lab_network"]
image { name = "postgres:13" }
network { id = resource.network.lab_network.meta.id }
environment = { POSTGRES_DB = "appdb" }}
# 3. Create application containerresource "container" "app" { depends_on = ["resource.container.database"]
image { name = "myapp:latest" }
network { id = resource.network.lab_network.meta.id }
environment = { DATABASE_HOST = resource.container.database.meta.name }}
# 4. Create user interfaceresource "service" "app_ui" { target = resource.container.app port = 8080 title = "My Application"}
# 5. Create terminal for accessresource "terminal" "app_terminal" { target = resource.container.app shell = "/bin/bash"}
Best Practices
Section titled “Best Practices”- Meaningful Names: Use descriptive resource names that indicate their purpose
- Explicit Dependencies: Use
depends_on
when resources need specific creation ordering - Resource Organization: Group related resources logically in your configuration
- Reference Patterns: Use resource references instead of hardcoding values
- Conditional Resources: Use the
disabled
field for optional components - Documentation: Include comments explaining complex resource configurations
Common Patterns
Section titled “Common Patterns”Multi-Tier Architecture
Section titled “Multi-Tier Architecture”# Database tierresource "container" "database" { image { name = "postgres:13" } container_name = "db-server"}
# Application tierresource "container" "api" { depends_on = ["resource.container.database"]
image { name = "api:latest" }
environment = { DB_HOST = resource.container.database.meta.name }}
# Presentation tierresource "container" "web" { depends_on = ["resource.container.api"]
image { name = "web:latest" }
environment = { API_URL = format("http://%s:8080", resource.container.api.meta.name) }}
Development Environment
Section titled “Development Environment”resource "container" "dev_environment" { image { name = "ubuntu:20.04" }
volume { source = "./workspace" destination = "/workspace" type = "bind" }}
resource "editor" "code_editor" { target = resource.container.dev_environment path = "/workspace"}
resource "terminal" "dev_terminal" { target = resource.container.dev_environment working_directory = "/workspace"}
Service Discovery
Section titled “Service Discovery”resource "network" "services" { subnet = "10.0.10.0/24"}
# Create multiple servicesresource "container" "services" { count = length(variable.service_names)
image { name = "${variable.service_names[count.index]}:latest" }
container_name = variable.service_names[count.index]
network { id = resource.network.services.meta.id }}
# Service discovery configurationoutput "service_endpoints" { value = { for i, name in variable.service_names : name => { host = resource.container.services[i].meta.name port = 8080 } }}
Resource Lifecycle
Section titled “Resource Lifecycle”Resources follow a predictable lifecycle:
- Parsing: HCL configuration is parsed and validated
- Dependency Resolution: Resource dependencies are analyzed and ordering determined
- Creation: Resources are created in dependency order
- Ready State: Resources become available for reference by other resources
- Runtime: Resources remain active during lab execution
- Cleanup: Resources are cleaned up when the lab ends
Understanding this lifecycle helps you design configurations that work reliably and predictably across different lab environments.