Skip to content

Instantly share code, notes, and snippets.

@mzupan
Created February 2, 2016 17:13
Show Gist options
  • Save mzupan/902978e485f1d6939c4a to your computer and use it in GitHub Desktop.
Save mzupan/902978e485f1d6939c4a to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
import os
import sys
import glob
import argparse
from subprocess import Popen, PIPE, STDOUT
try:
from jinja2 import Template, Environment, FileSystemLoader
except:
print
print "Need to install jinja2"
print " -- pip install jinja2"
sys.exit(2)
parser = argparse.ArgumentParser(description='A wrapper for terraform that adds jinja templating')
parser.add_argument('-e', action="store", dest="env", type=str, help='The environment to use')
parser.add_argument('-t', action="store", dest="test", type=bool, help='Just runs a terraform plan then exits')
results = parser.parse_args()
env = results.env
if env is None:
env = "dev"
PATH = os.path.dirname(os.path.abspath(__file__))
TEMPLATE_ENVIRONMENT = Environment(
autoescape=False,
loader=FileSystemLoader(os.path.join(PATH, 'templates')),
trim_blocks=False)
def render_template(template_filename, context):
return TEMPLATE_ENVIRONMENT.get_template(template_filename).render(context)
#
# thanks to http://stackoverflow.com/a/3041990/72987
def query_yes_no(question, default="no"):
"""Ask a yes/no question via raw_input() and return their answer.
"question" is a string that is presented to the user.
"default" is the presumed answer if the user just hits <Enter>.
It must be "yes" (the default), "no" or None (meaning
an answer is required of the user).
The "answer" return value is True for "yes" or False for "no".
"""
valid = {"yes": True, "y": True, "ye": True,
"no": False, "n": False}
if default is None:
prompt = " [y/n] "
elif default == "yes":
prompt = " [Y/n] "
elif default == "no":
prompt = " [y/N] "
else:
raise ValueError("invalid default answer: '%s'" % default)
while True:
sys.stdout.write(question + prompt)
choice = raw_input().lower()
if default is not None and choice == '':
return valid[default]
elif choice in valid:
return valid[choice]
else:
sys.stdout.write("Please respond with 'yes' or 'no' "
"(or 'y' or 'n').\n")
def run_command(cmd):
#
# runs a command and streams the output
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True, cwd='./output', bufsize=1)
with p.stdout:
for line in iter(p.stdout.readline, b''):
print line,
p.wait()
def run_terraform():
context = {'env': env}
for f in glob.glob("%s/templates/*.jinja" % PATH):
f = os.path.basename(f)
#
# generate the template
t = render_template(f, context)
#
# replace .jinja with .tf
f = os.path.splitext(f)[0] + ".tf"
#
# save the template
with open("./output/%s" % f, "w") as output:
output.write(t)
#
# run 'terraform plan' now
cmd = "terraform plan -state=../%s.tfstate -var-file=../%s.tfvars -var 'env=%s'" % (env, env, env)
run_command(cmd)
#
# prompt
print
print
if not query_yes_no("Do you want to apply the changed?"):
sys.exit(2)
#
# run 'terraform apply' now
cmd = "terraform apply -state=../%s.tfstate -var-file=../%s.tfvars -var 'env=%s'" % (env, env, env)
run_command(cmd)
#
# clean out the output
map(os.unlink, [os.path.join("./output", f) for f in os.listdir("./output")])
def main():
run_terraform()
########################################
if __name__ == "__main__":
main()
#!/bin/bash
#
# pulling first
git pull origin master
ENV=$1
if [ -z "$ENV" ]; then ENV='dev'; fi
python ./terra.py -e $ENV
#
# committing.
if [ "$?" = "0" ]
then
git add *
git commit -a -m "auto import"
git push origin master
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment