| // Copyright IBM Corp. 2014, 2026 | |
| // SPDX-License-Identifier: BUSL-1.1 | |
| package command | |
| import ( | |
| "fmt" | |
| "strings" | |
| "github.com/hashicorp/terraform/internal/command/arguments" | |
| "github.com/hashicorp/terraform/internal/command/views" | |
| "github.com/hashicorp/terraform/internal/states" | |
| "github.com/hashicorp/terraform/internal/tfdiags" | |
| ) | |
| // OutputCommand is a Command implementation that reads an output | |
| // from a Terraform state and prints it. | |
| type OutputCommand struct { | |
| Meta | |
| } | |
| func (c *OutputCommand) Run(rawArgs []string) int { | |
| // Parse and apply global view arguments | |
| common, rawArgs := arguments.ParseView(rawArgs) | |
| c.View.Configure(common) | |
| // Parse and validate flags | |
| args, diags := arguments.ParseOutput(rawArgs) | |
| if diags.HasErrors() { | |
| c.View.Diagnostics(diags) | |
| c.View.HelpPrompt("output") | |
| return 1 | |
| } | |
| view := views.NewOutput(args.ViewType, c.View) | |
| // Fetch data from state | |
| outputs, diags := c.Outputs(args.StatePath, args.ViewType) | |
| if diags.HasErrors() { | |
| view.Diagnostics(diags) | |
| return 1 | |
| } | |
| // Render the view | |
| viewDiags := view.Output(args.Name, outputs) | |
| diags = diags.Append(viewDiags) | |
| view.Diagnostics(diags) | |
| if diags.HasErrors() { | |
| return 1 | |
| } | |
| return 0 | |
| } | |
| func (c *OutputCommand) Outputs(statePath string, view arguments.ViewType) (map[string]*states.OutputValue, tfdiags.Diagnostics) { | |
| var diags tfdiags.Diagnostics | |
| // Allow state path override | |
| if statePath != "" { | |
| c.Meta.statePath = statePath | |
| } | |
| // Load the backend | |
| b, backendDiags := c.backend(".", view) | |
| diags = diags.Append(backendDiags) | |
| if backendDiags.HasErrors() { | |
| return nil, diags | |
| } | |
| // Command can be aborted by interruption signals | |
| ctx, done := c.InterruptibleContext(c.CommandContext()) | |
| defer done() | |
| // This is a read-only command | |
| c.ignoreRemoteVersionConflict(b) | |
| env, err := c.Workspace() | |
| if err != nil { | |
| diags = diags.Append(fmt.Errorf("Error selecting workspace: %s", err)) | |
| return nil, diags | |
| } | |
| // Get the state | |
| sMgr, sDiags := b.StateMgr(env) | |
| if sDiags.HasErrors() { | |
| diags = diags.Append(fmt.Errorf("Failed to load state: %s", sDiags.Err())) | |
| return nil, diags | |
| } | |
| output, err := sMgr.GetRootOutputValues(ctx) | |
| if err != nil { | |
| return nil, diags.Append(err) | |
| } | |
| return output, diags | |
| } | |
| func (c *OutputCommand) Help() string { | |
| helpText := ` | |
| Usage: terraform [global options] output [options] [NAME] | |
| Reads an output variable from a Terraform state file and prints | |
| the value. With no additional arguments, output will display all | |
| the outputs for the root module. If NAME is not specified, all | |
| outputs are printed. | |
| Options: | |
| -state=path Path to the state file to read. Defaults to | |
| "terraform.tfstate". | |
| Legacy option for the local backend only. See | |
| the local backend's documentation for more | |
| information. | |
| -no-color If specified, output won't contain any color. | |
| -json If specified, machine readable output will be | |
| printed in JSON format. | |
| -raw For value types that can be automatically | |
| converted to a string, will print the raw | |
| string directly, rather than a human-oriented | |
| representation of the value. | |
| ` | |
| return strings.TrimSpace(helpText) | |
| } | |
| func (c *OutputCommand) Synopsis() string { | |
| return "Show output values from your root module" | |
| } |