Skip to content

Instantly share code, notes, and snippets.

@amalagaura
Created April 24, 2026 17:04
Show Gist options
  • Select an option

  • Save amalagaura/d5fcd1b24b2b0fe3446c35e1d1acbbb3 to your computer and use it in GitHub Desktop.

Select an option

Save amalagaura/d5fcd1b24b2b0fe3446c35e1d1acbbb3 to your computer and use it in GitHub Desktop.
tf-attr-editor - Edit attributes within a list of HCL objects
#!/usr/bin/env python3
"""
tf-attr-editor - Edit attributes within a list of HCL objects
"""
import argparse
import subprocess
import sys
from pathlib import Path
import hcl2
__version__ = "0.4.3-debug"
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-file", required=True)
parser.add_argument("-path", required=True)
parser.add_argument("-pos", type=int, required=True)
parser.add_argument("-field", required=True)
parser.add_argument("-value", required=True)
parser.add_argument("--debug", action="store_true", help="Print parsed HCL structure")
parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
args = parser.parse_args()
file_path = Path(args.file)
if not file_path.exists():
print(f"Error: file {file_path} does not exist", file=sys.stderr)
sys.exit(1)
# Parse HCL
try:
with open(file_path, "r", encoding="utf-8") as f:
data = hcl2.load(f)
except Exception as e:
print(f"Error: invalid HCL: {e}", file=sys.stderr)
sys.exit(1)
if args.debug:
print("=== DEBUG: Parsed HCL structure ===")
import pprint
pprint.pprint(data, indent=2)
print("=================================")
# Try to find the list
target_list = None
# Case 1: Top-level list
if args.path in data and isinstance(data[args.path], list):
target_list = data[args.path]
# Case 2: locals.my_list
elif args.path.startswith("locals."):
list_name = args.path.split(".")[-1]
for loc in data.get("locals", []):
if isinstance(loc, dict) and list_name in loc and isinstance(loc[list_name], list):
target_list = loc[list_name]
break
# Case 3: Just "my_list" inside locals
elif args.path == "my_list":
for loc in data.get("locals", []):
if isinstance(loc, dict) and "my_list" in loc and isinstance(loc["my_list"], list):
target_list = loc["my_list"]
break
if target_list is None:
print(f"Error: list '{args.path}' not found", file=sys.stderr)
print("Tip: Run with --debug to see the parsed structure", file=sys.stderr)
sys.exit(1)
# Rest of the logic (unchanged)
if not isinstance(target_list, list) or args.pos < 0 or args.pos >= len(target_list):
print(f"Error: position {args.pos} is out of bounds", file=sys.stderr)
sys.exit(1)
target_obj = target_list[args.pos]
if not isinstance(target_obj, dict):
print(f"Error: element at position {args.pos} is not an object", file=sys.stderr)
sys.exit(1)
if args.field in target_obj:
print(f"Error: field '{args.field}' already exists", file=sys.stderr)
sys.exit(1)
target_obj[args.field] = args.value
try:
with open(file_path, "w", encoding="utf-8") as f:
hcl2.dump(data, f)
except Exception as e:
print(f"Error: failed to write file: {e}", file=sys.stderr)
sys.exit(1)
try:
subprocess.run(["terraform", "fmt", "-write=true", str(file_path)], check=True, capture_output=True)
except Exception:
pass
print(f"✅ Successfully added '{args.field}' to object at position {args.pos} in {args.path}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment