Skip to content

Instantly share code, notes, and snippets.

@rhowe
Created December 24, 2025 10:48
Show Gist options
  • Select an option

  • Save rhowe/e63878973978ef7d5b895806772b4d1d to your computer and use it in GitHub Desktop.

Select an option

Save rhowe/e63878973978ef7d5b895806772b4d1d to your computer and use it in GitHub Desktop.
Terraform module composer
#!/usr/bin/python3
import json
import os
from subprocess import run
combined_statefile = 'terraform.tfstate'
state_dir = "statefiles"
run(['terraform', 'init'])
with open("main.tf.json", "r") as tf:
wrapper = json.load(tf)
modules_from_tf = [k for k in wrapper['module']]
modules_from_statefiles = [f.removesuffix('.tfstate') for f in os.listdir(state_dir) if f.endswith('.tfstate')]
modules = set(modules_from_tf + modules_from_statefiles)
for module in modules:
statefile = os.path.join(state_dir, f'{module}.tfstate')
if os.path.exists(statefile):
states = run(['terraform', 'state', 'list', '-state', statefile], capture_output=True)
state_ids = [state_id for state_id in states.stdout.decode('utf-8').split('\n') if state_id]
for state in state_ids:
dest_state_id = f'module.{module}.{state}'
run(['terraform', 'state', 'mv', '-state', statefile, '-state-out', combined_statefile, state, dest_state_id])
run(['terraform', 'plan', '-out', 'tf.plan'])
run(['terraform', 'apply', 'tf.plan'])
state = run(['terraform', 'state', 'list'], capture_output=True)
state_ids = state.stdout.decode('utf-8').split('\n')
for state in state_ids:
for module in modules:
module_prefix = f'module.{module}.'
if state.startswith(module_prefix):
run(['terraform', 'state', 'mv', '-state', combined_statefile, '-state-out', os.path.join(state_dir, f'{module}.tfstate'), state, state.removeprefix(module_prefix)])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment