Skip to content

Output

The output resource defines values that can be accessed from outside the current configuration module. Output values make information about your lab resources available for inspection, reuse in other configurations, or integration with external systems. They serve as the return values of your lab configuration.

As a lab author, you can use output values to expose important information:

  • Resource Information: Expose key details about created resources (names, IDs, addresses, ports) for reference
  • Module Integration: Provide outputs from modules that can be consumed by parent configurations or other modules
  • Debugging and Inspection: Make internal values visible for troubleshooting and verification purposes
  • External System Integration: Expose configuration values needed by external tools or systems
  • Lab User Information: Provide users with access details, URLs, or credentials they need to complete lab tasks
  • Cross-Configuration References: Share computed values between different lab configurations or environments

Output values create a clean interface for making internal lab state accessible to external consumers.

output "name" {
value = "output_value"
}
output "container_info" {
value = resource.container.web.meta.name
description = "Name of the web container for user reference"
}
FieldRequiredTypeDescription
valueanyThe output value expression (can be string, number, boolean, list, or object)
descriptionstringHuman-readable description of the output’s purpose
depends_onlist(string)List of resource dependencies (inherited from ResourceBase)
disabledboolWhether this output is disabled. Defaults to false.

Output values are referenced from modules using the syntax:

module.module_name.output.output_name
output "web_container_name" {
value = resource.container.web.meta.name
description = "Name of the web container"
}
output "database_connection" {
value = {
host = resource.container.postgres.meta.name
port = 5432
database = "myapp"
username = variable.db_username
}
description = "Database connection information for applications"
}
output "service_ports" {
value = [
resource.container.web.port[0].local,
resource.container.api.port[0].local,
resource.container.admin.port[0].local
]
description = "All service ports exposed by the lab"
}
output "application_url" {
value = format("http://%s:%d", resource.container.web.meta.name, resource.container.web.port[0].local)
description = "Full URL to access the web application"
}
output "debug_info" {
value = variable.debug_enabled ? {
container_logs = "/tmp/logs"
debug_port = 9229
profiler_url = "http://localhost:9229"
} : null
description = "Debug information (only available when debug mode is enabled)"
}
output "cluster_info" {
value = {
cluster_name = resource.kubernetes_cluster.main.meta.name
kubeconfig = resource.kubernetes_cluster.main.kubeconfig_path
api_server = "https://localhost:6443"
nodes = [
for node in resource.kubernetes_cluster.main.nodes : {
name = node.name
role = node.role
}
]
}
description = "Kubernetes cluster connection and node information"
}
output "lab_status" {
value = {
ready = alltrue([
resource.container.database.meta.status == "running",
resource.container.web.meta.status == "running",
resource.container.api.meta.status == "running"
])
services = {
database = resource.container.database.meta.status
web = resource.container.web.meta.status
api = resource.container.api.meta.status
}
}
description = "Overall lab readiness status and individual service states"
}
output "lab_access" {
value = {
web_ui_url = format("http://localhost:%d", resource.container.web.port[0].local)
ssh_command = format("ssh -p %d root@localhost", resource.container.server.port[0].local)
database_cli = format("psql -h %s -p 5432 -U admin myapp", resource.container.postgres.meta.name)
admin_panel = format("http://localhost:%d/admin", resource.container.web.port[0].local)
}
description = "Access information for lab users"
}
output "environment_summary" {
value = {
environment = variable.environment
created_at = formatdate("RFC3339", timestamp())
resource_count = length([
resource.container.web,
resource.container.api,
resource.container.database
])
features_enabled = {
monitoring = variable.enable_monitoring
logging = variable.enable_logging
debugging = variable.debug_enabled
}
network_config = {
subnet = resource.network.main.subnet
containers = [
for container in [resource.container.web, resource.container.api, resource.container.database] :
container.meta.name
]
}
}
description = "Complete environment configuration summary"
}
  1. Descriptive Names: Use clear, descriptive names that indicate what information the output provides
  2. Include Descriptions: Always provide descriptions to document the output’s purpose and format
  3. Group Related Information: Use objects to group related output values together
  4. User-Focused Values: Prioritize outputs that provide value to lab users or consuming systems
  5. Stable Interfaces: Keep output schemas stable to avoid breaking integrations
  6. Security Considerations: Avoid outputting sensitive information like passwords or private keys
output "services" {
value = {
for service_name, container in {
web = resource.container.web
api = resource.container.api
database = resource.container.database
} : service_name => {
name = container.meta.name
host = container.meta.name
port = length(container.port) > 0 ? container.port[0].local : null
}
}
description = "Service discovery information for all lab services"
}
output "lab_validation" {
value = {
all_containers_running = alltrue([
for container in [resource.container.web, resource.container.api, resource.container.db] :
container.meta.status == "running"
])
required_files_exist = alltrue([
resource.template.config.destination != "",
resource.template.startup.destination != ""
])
network_connectivity = resource.network.main.meta.id != ""
}
description = "Validation checks for lab completion"
}
# In a reusable module
output "module_interface" {
value = {
# Required outputs for module consumers
primary_service_url = format("http://%s:%d", resource.container.main.meta.name, 8080)
admin_credentials = {
username = variable.admin_username
# Note: Don't output actual passwords
password_hint = "Check the container environment variables"
}
# Optional debugging information
internal_services = var.debug_mode ? {
cache_host = resource.container.cache.meta.name
db_host = resource.container.database.meta.name
} : null
}
description = "Public interface for this module"
}

Outputs support all HCL data types:

Type Example Use Case
string value = resource.container.web.meta.name Names, URLs, file paths
number value = resource.container.web.port[0].local Ports, counts, resource limits
bool value = variable.debug_enabled Status flags, feature toggles
list value = [for c in var.containers : c.name] Collections of similar items
object value = { host = "...", port = 80 } Structured configuration data
output "monitoring_config" {
value = {
targets = [
for container in [resource.container.web, resource.container.api] : {
job = container.meta.name
targets = ["${container.meta.name}:${container.port[0].local}"]
labels = {
environment = variable.environment
service = container.meta.name
}
}
]
}
description = "Prometheus monitoring configuration"
}

Output values provide a clean, documented interface for making your lab’s internal state accessible to users and external systems, supporting both simple values and complex structured data.