diff --git a/ansible/terraform.py b/ansible/terraform.py index 7ab2138..8d8d4f4 100755 --- a/ansible/terraform.py +++ b/ansible/terraform.py @@ -6,8 +6,16 @@ import re import subprocess import sys +def _tf_env(): + # way to figure out currenly used TF workspace + with open(TERRAFORM_ENV) as f: + return f.read() + TERRAFORM_PATH = os.environ.get('ANSIBLE_TF_BIN', 'terraform') TERRAFORM_DIR = os.environ.get('ANSIBLE_TF_DIR', os.getcwd()) +TERRAFORM_BPK = os.path.join(TERRAFORM_DIR, '.terraform/terraform.tfstate.backup') +TERRAFORM_ENV = os.path.join(TERRAFORM_DIR, '.terraform/environment') +ANSIBLE_BKP = os.path.join(TERRAFORM_DIR, 'ansible/inventory', _tf_env()) def _extract_dict(attrs, key): out = {} @@ -99,14 +107,48 @@ def _walk_state(tfstate, inventory): return inventory +def _backup_tf(tfstate): + # Crates a state backup in case we lose Consul + with open(TERRAFORM_BPK, 'w') as f: + f.write(json.dumps(tfstate)) + +def _backup_ansible(inventory): + # Crates a state backup in Ansible inventory format + text = '# NOTE: This file is generated by terraform.py\n' + text += '# For emergency use when Consul fails\n' + text += '[all]\n' + for host in inventory['_meta']['hostvars'].values(): + text += ( + '{hostname} hostname={hostname} ansible_host={ansible_host} '+ + 'env={env} stage={stage} data_center={data_center} region={region} '+ + 'dns_entry={dns_entry}\n' + ).format(**host) + text += '\n' + for name, hosts in inventory.iteritems(): + if name == '_meta': + continue + text += '[{}]\n'.format(name) + for host in hosts['hosts']: + text += '{}\n'.format(host) + text += '\n' + with open(ANSIBLE_BKP, 'w') as f: + f.write(text) + def _main(): try: tf_command = [TERRAFORM_PATH, 'state', 'pull', '-input=false'] proc = subprocess.Popen(tf_command, cwd=TERRAFORM_DIR, stdout=subprocess.PIPE) tfstate = json.load(proc.stdout) + # format state for ansible inventory = _walk_state(tfstate, _init_inventory()) + # print out for ansible sys.stdout.write(json.dumps(inventory, indent=2)) - except: + # backup raw TF state + _backup_tf(tfstate) + # backup ansible inventory + _backup_ansible(inventory) + except Exception as ex: + print(ex) sys.exit(1) if __name__ == '__main__':