Skip to content

Instantly share code, notes, and snippets.

@nitrocode
Last active April 29, 2020 14:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nitrocode/7c2f5386f144c7b06e38c2c38292889e to your computer and use it in GitHub Desktop.
Save nitrocode/7c2f5386f144c7b06e38c2c38292889e to your computer and use it in GitHub Desktop.
Guesses terraform imports based on outputted plan
#!/usr/bin/env python3
# Currently works for 0.12.x
#
# TODO:
# - use json output instead of stdout
#
# Usage:
# terraform plan > plan.out
# python terraform-import-statement-guesser.py plan.out
import sys
import re
# https://stackoverflow.com/a/38662876/2965993
def escape_ansi(line):
ansi_escape = re.compile(r'(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]')
return ansi_escape.sub('', line)
plan_file = sys.argv[1]
with open(plan_file, "r") as f:
destroyed = []
created = []
for line in f:
line = escape_ansi(line.rstrip("\n"))
if not 'will be' in line:
continue
line_split = line.split()
resource_name = line_split[2]
created_or_destroyed = line_split[-1]
if 'destroyed' in created_or_destroyed:
destroyed.append(resource_name)
elif 'created' in created_or_destroyed:
created.append(resource_name)
else:
print('dafuq')
continue
# iterate through all the created resources
not_found = []
for resource in created:
# get the short resource name
resource_name = resource_name_trimmed = resource.split('.')[-1]
# trim the array portion if it exists
if '[' in resource_name:
resource_name_trimmed = resource_name[:resource_name.find('[')]
# iterate through all the destroyed resources and see which one matches the created one
found = False
for des_resource in destroyed:
# do the same thing. get the short resource name of destroyed, trim it
des_resource_name = des_resource_name_trimmed = des_resource.split('.')[-1]
if '[' in des_resource_name:
des_resource_name_trimmed = des_resource_name[:des_resource_name.find('[')]
# funky logic and is error prone
## if the untrimmed names match, print the move statement
## or if the trimmed names match, print the move statement
if (des_resource_name == resource_name) or (des_resource_name_trimmed == resource_name_trimmed):
print('terraform state mv "{}" "{}"'.format(des_resource, resource))
found = True
break
if not found:
not_found.append(resource)
if len(not_found) > 0:
print('Could not find instances...')
for resource in not_found:
print(resource)
terraform show \
-json | \
jq -r \
'.values.root_module.resources[].address' | \
while read address; do \
echo "terraform state mv $address module.ecs_shared.$address"; \
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment