0
# Command Interface & Utilities
1
2
Generic command execution interface and utility functions for building terraform commands, managing execution, and retrieving outputs. This provides the foundation for all terraform operations and enables access to any terraform command.
3
4
## Capabilities
5
6
### Generic Command Execution
7
8
Execute any terraform command with full control over arguments, options, and execution behavior.
9
10
```python { .api }
11
def cmd(self, cmd: str, *args, capture_output: Union[bool, str] = True,
12
raise_on_error: bool = True, synchronous: bool = True, **kwargs) -> CommandOutput:
13
"""
14
Execute arbitrary terraform command.
15
16
Args:
17
cmd: Command and sub-command of terraform, separated by space
18
*args: Positional arguments for the command
19
capture_output: Output capture mode:
20
- True: Capture stdout/stderr and return as strings
21
- False: Print output to terminal in real-time, return None
22
- "framework": No capture, return None for both streams
23
raise_on_error: Raise TerraformCommandError on non-zero exit (default: True)
24
synchronous: Wait for command completion (default: True)
25
**kwargs: Command options converted to terraform flags
26
27
Returns:
28
Tuple of (return_code, stdout, stderr)
29
30
Raises:
31
TerraformCommandError: If command fails and raise_on_error=True
32
"""
33
```
34
35
Usage examples:
36
37
```python
38
# Execute import command
39
return_code, stdout, stderr = tf.cmd('import', 'aws_instance.example', 'i-1234567890abcdef0')
40
41
# Execute refresh command
42
return_code, stdout, stderr = tf.cmd('refresh', var={'environment': 'prod'})
43
44
# Execute validate command
45
return_code, stdout, stderr = tf.cmd('validate')
46
47
# Execute state operations
48
return_code, stdout, stderr = tf.cmd('state', 'list')
49
return_code, stdout, stderr = tf.cmd('state', 'show', 'aws_instance.example')
50
51
# Real-time output for long-running commands
52
return_code, stdout, stderr = tf.cmd('apply', capture_output=False)
53
54
# Non-blocking execution
55
return_code, stdout, stderr = tf.cmd('apply', synchronous=False)
56
```
57
58
### Command String Generation
59
60
Build terraform command strings without executing them, useful for debugging or custom execution workflows.
61
62
```python { .api }
63
def generate_cmd_string(self, cmd: str, *args, **kwargs) -> List[str]:
64
"""
65
Generate terraform command arguments list without execution.
66
67
Args:
68
cmd: Command and sub-command of terraform, separated by space
69
*args: Positional arguments for the command
70
**kwargs: Command options converted to terraform flags
71
72
Returns:
73
List of command arguments suitable for subprocess execution
74
"""
75
```
76
77
Usage examples:
78
79
```python
80
# Generate apply command with options
81
cmd_args = tf.generate_cmd_string('apply',
82
var={'env': 'prod'},
83
no_color=IsFlagged,
84
target=['aws_instance.web'])
85
print(' '.join(cmd_args))
86
# Output: terraform apply -var=env=prod -no-color -target=aws_instance.web
87
88
# Generate import command
89
cmd_args = tf.generate_cmd_string('import', 'aws_instance.example', 'i-1234567890abcdef0')
90
print(' '.join(cmd_args))
91
# Output: terraform import aws_instance.example i-1234567890abcdef0
92
93
# Generate plan command with variable file
94
cmd_args = tf.generate_cmd_string('plan', var_file='production.tfvars', out='prod.tfplan')
95
print(' '.join(cmd_args))
96
# Output: terraform plan -var-file=production.tfvars -out=prod.tfplan
97
```
98
99
### Output Retrieval
100
101
Retrieve terraform outputs with automatic JSON parsing and flexible return formats.
102
103
```python { .api }
104
def output(self, *args, capture_output: bool = True, **kwargs) -> Union[None, str, Dict[str, str], Dict[str, Dict[str, str]]]:
105
"""
106
Retrieve terraform output values with JSON parsing.
107
108
Args:
109
*args: Optional output name. If provided, returns single output value.
110
capture_output: Must be True for this method (default: True)
111
full_value: If True and output name provided, return full output metadata
112
**kwargs: Additional terraform output options
113
114
Returns:
115
- None: If command failed
116
- str: Output value if name provided and full_value=False
117
- Dict: Output metadata if name provided and full_value=True
118
- Dict[str, Dict]: All outputs with metadata if no name provided
119
120
Note: This method automatically adds -json flag and parses the result.
121
"""
122
```
123
124
Usage examples:
125
126
```python
127
# Get all outputs
128
outputs = tf.output()
129
if outputs:
130
for name, output_data in outputs.items():
131
print(f"{name}: {output_data['value']}")
132
133
# Get specific output value
134
database_url = tf.output('database_url')
135
print(f"Database URL: {database_url}")
136
137
# Get output with metadata
138
output_info = tf.output('database_url', full_value=True)
139
if output_info:
140
print(f"Value: {output_info['value']}")
141
print(f"Type: {output_info['type']}")
142
print(f"Sensitive: {output_info['sensitive']}")
143
```
144
145
### Dynamic Method Access
146
147
Access any terraform command as a method through Python's `__getattr__` mechanism.
148
149
```python { .api }
150
def __getattr__(self, item: str) -> Callable:
151
"""
152
Dynamically create methods for terraform commands.
153
154
Terraform commands become Python methods:
155
- Command names ending in '_cmd' are handled (import_cmd, etc.)
156
- All other names are passed through as terraform commands
157
158
Returns:
159
Callable that executes the terraform command
160
"""
161
```
162
163
Usage examples:
164
165
```python
166
# These are equivalent:
167
return_code, stdout, stderr = tf.cmd('import', 'aws_instance.example', 'i-1234567890abcdef0')
168
return_code, stdout, stderr = tf.import_cmd('aws_instance.example', 'i-1234567890abcdef0')
169
170
# Other command examples
171
return_code, stdout, stderr = tf.validate_cmd()
172
return_code, stdout, stderr = tf.refresh_cmd()
173
return_code, stdout, stderr = tf.fmt_cmd(diff=True)
174
return_code, stdout, stderr = tf.graph_cmd()
175
return_code, stdout, stderr = tf.show_cmd()
176
```
177
178
## Option Conversion Rules
179
180
The library automatically converts Python-style options to terraform CLI flags:
181
182
### Naming Convention
183
- **Underscores to dashes**: `no_color` → `-no-color`
184
- **Method name handling**: Commands ending with `_cmd` have suffix removed
185
186
### Value Types
187
- **IsFlagged**: Adds flag without value (`no_color=IsFlagged` → `-no-color`)
188
- **IsNotFlagged/None**: Skips the option entirely
189
- **Boolean**: Converts to string (`refresh=True` → `-refresh=true`)
190
- **String/Number**: Adds as key-value pair (`parallelism=5` → `-parallelism=5`)
191
- **List**: Adds multiple flags (`target=['a', 'b']` → `-target=a -target=b`)
192
- **Dictionary for var**: Creates temporary variable file or individual flags
193
- **Dictionary for backend-config**: Individual backend config flags
194
195
### Examples
196
```python
197
# Python options
198
tf.plan(
199
no_color=IsFlagged,
200
detailed_exitcode=IsFlagged,
201
refresh=True,
202
var={'environment': 'prod', 'count': '3'},
203
target=['aws_instance.web'],
204
parallelism=5
205
)
206
207
# Equivalent terraform command:
208
# terraform plan -no-color -detailed-exitcode -refresh=true -var-file=temp_vars.tfvars.json -target=aws_instance.web -parallelism=5
209
```
210
211
## Error Handling and Execution Control
212
213
### Capture Modes
214
```python
215
# Capture output (default)
216
return_code, stdout, stderr = tf.cmd('plan')
217
218
# Real-time output to terminal
219
return_code, stdout, stderr = tf.cmd('apply', capture_output=False)
220
# stdout and stderr will be None, output goes to terminal
221
222
# Framework mode (no capture or display)
223
return_code, stdout, stderr = tf.cmd('validate', capture_output="framework")
224
```
225
226
### Error Control
227
```python
228
# Default: raise exception on error
229
try:
230
return_code, stdout, stderr = tf.cmd('apply')
231
except TerraformCommandError as e:
232
print(f"Command failed: {e.cmd}")
233
print(f"Return code: {e.returncode}")
234
print(f"Error output: {e.err}")
235
236
# Don't raise exception, handle manually
237
return_code, stdout, stderr = tf.cmd('plan', raise_on_error=False)
238
if return_code != 0:
239
print(f"Plan failed with code {return_code}")
240
print(f"Error: {stderr}")
241
```
242
243
### Asynchronous Execution
244
```python
245
# Start command without waiting
246
return_code, stdout, stderr = tf.cmd('apply', synchronous=False)
247
# All return values will be None
248
# Command continues running in background
249
```