Skip to content

Instantly share code, notes, and snippets.

@it-is-wednesday
Last active April 2, 2023 10:15
Show Gist options
  • Save it-is-wednesday/1ffe985c45a2be7d6cf9b6c803a87d6e to your computer and use it in GitHub Desktop.
Save it-is-wednesday/1ffe985c45a2be7d6cf9b6c803a87d6e to your computer and use it in GitHub Desktop.
# pylint: disable=line-too-long
"""
https://kevincox.ca/2020/09/09/terraform-debug/
"""
import ast
import os
import json
from pathlib import Path
from subprocess import PIPE, STDOUT, Popen
from tempfile import mkstemp
PROJ_DIR = Path("~/dev/avocadosh-apps").expanduser()
STARTSWITH = '{"@level":"error","@message":"Error: Invalid function argument","@module"'
DETAILS_PREFIX = 'Invalid value for "path" parameter: no file exists at "'
DETAILS_SUFFIX = '"; this function works only with files that are distributed as part of the configuration source code, so if this file will be created by a resource in this configuration you must instead obtain this result from an attribute of that resource.'
def plan():
cmd = ["terraform", "plan", "-json"]
with Popen(cmd, stdout=PIPE, stderr=STDOUT, cwd=PROJ_DIR) as proc:
for raw_line in proc.stdout:
line = raw_line.decode()
if line.startswith(STARTSWITH):
details = json.loads(line)["diagnostic"]["detail"]
only_json = details.removeprefix(DETAILS_PREFIX).removesuffix(DETAILS_SUFFIX)
removed_backslashes = ast.literal_eval(f'"{only_json}"')
return json.loads(removed_backslashes)
def create_temp_file_in_root(expression_to_print):
path = Path(mkstemp(dir=PROJ_DIR, suffix=".tf", text=True)[1])
abomination = f"file(jsonencode({expression_to_print}))"
with path.open("w", encoding="UTF-8") as tmp_tf:
tmp_tf.write(f'output "asdasdasd"{{\nvalue={abomination}\n}}')
tmp_tf.flush()
out = plan()
os.unlink(path)
return out
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment