Updated 2017-12-06: complete re-write to support nested braces in variable description
Updated 2017-12-05: support minimal variable declaration, eg. variable "foo" {}
When developing terraform code, it is easy to end up with a bunch of variable definitions that are listed in no particular order.
Here's a bit of python code that will sort terraform variable definitions. Use it as a filter from inside vim, or as a standalone tool if you have all your variable definitions in one file.
eg:
tf_sort < variables.tf > variables.tf.sorted
mv variables.tf.sorted variables.tf
Here's the code:
#!/usr/bin/env python
# sort terraform variables
import sys
import regex
# this regex matches terraform variable definitions
# we capture the variable name so we can sort on it
pattern = regex.compile('''
( # capturing group #1
variable # literal text
\s* # white space (optional)
" # literal quote character
)
( # capturing group #2 (variable name)
[^"]+ # anything except another quote
)
( # capturing group #3
" # literal quote character
\s* # white space (optional)
)
(?<rec> # capturing group named "rec"
{ # literal left brace
(?: # non-capturing group
[^{}]++ # anything but braces one or more times with no backtracking
| # or
(?&rec) # recursive substitution of group "rec"
)* # this group can appear 0 or more times
} # literal right brace
)
''', regex.VERBOSE)
def process(content):
# sort the content (a list of tuples) on the second item of the tuple
# (which is the variable name)
matches = sorted(regex.findall(pattern, content), key=lambda x: x[1])
# iterate over the sorted list and output them
for match in matches:
print(''.join(map(str, match)))
# don't print the newline on the last item
if match != matches[-1]:
print('')
# check if we're reading from stdin
if not sys.stdin.isatty():
stdin = sys.stdin.read()
if stdin:
process(stdin)
# process any filenames on the command line
for filename in sys.argv[1:]:
with open(filename) as f:
process(f.read())