2019-04-09 16:54:28 +02:00
#!/usr/bin/env python3
2019-04-10 13:47:03 +02:00
import argparse , subprocess , shlex , sys , os , glob
2019-04-09 16:54:28 +02:00
def main ( argv ) :
parser = argparse . ArgumentParser ( description = ' Control Terraform Workspaces. ' )
2019-04-10 12:00:01 +02:00
g = parser . add_mutually_exclusive_group ( )
g . add_argument ( " command " , help = " Send commands to terraform with workspace variable context " , nargs = ' ? ' , default = False )
2019-04-17 11:44:14 +02:00
parser . add_argument ( " -e " , help = " Gather shared-creds from environment variables (Dont use this flag if you dont want your ~/.aws/credentials replaced. This is for CI/CD " , action = ' store_true ' , default = False )
parser . add_argument ( " -m " , help = " Prevents workspace from changing with git branches automatically " , action = ' store_true ' , default = False )
2019-07-16 13:09:32 +02:00
parser . add_argument ( " -p " , help = " Atmos will not add -var-file or -var args to terraform " , action = ' store_true ' , default = False )
2019-04-10 12:00:01 +02:00
args , params = parser . parse_known_args ( )
if args . command :
determine_actions ( args , params )
def determine_actions ( args , params ) :
2019-07-16 17:12:34 +02:00
aws_creds_file = " $HOME/.aws/credentials "
2019-04-17 11:44:14 +02:00
if ( is_git_directory ( ) ) and not ( args . m ) :
2019-07-16 17:12:34 +02:00
aws_creds_file = aws_creds_file + " -atmos "
2019-04-17 11:44:14 +02:00
workspace_manager ( )
2019-04-15 15:15:39 +02:00
workspace = get_env ( )
2019-04-10 12:00:01 +02:00
env_actions = [ " plan " , " apply " , " destroy " ] # Commands that require env context
cmd = ' terraform {args} ' . format ( args = args . command )
2019-06-12 15:55:01 +02:00
if ( args . command in env_actions ) and not ( args . p ) : # Append with env context
2019-07-16 17:12:34 +02:00
cmd = cmd + ' -var-file=vars/ {env} .tfvars -var " workspace= {env} " -var " shared_credentials_file= {aws_creds_file} " ' . format ( env = workspace , aws_creds_file = aws_creds_file )
2019-06-12 15:55:01 +02:00
2019-04-10 12:00:01 +02:00
for param in params : # Pass terraform params directly through
cmd = cmd + ' ' + param
2019-04-17 10:59:30 +02:00
if ( args . e ) :
2019-04-15 15:15:39 +02:00
generate_creds ( )
2019-04-17 10:53:05 +02:00
2019-04-15 15:15:39 +02:00
print ( ' Terraform {args} using env vars in {env} ' . format ( args = args . command , env = workspace ) )
2019-04-10 12:00:01 +02:00
with subprocess . Popen ( shlex . split ( cmd ) ) as proc :
exit # Start process but kill py program
2019-04-17 10:53:05 +02:00
def is_git_directory ( path = ' . ' ) :
2019-04-17 11:44:14 +02:00
return subprocess . call ( [ ' git ' , ' -C ' , path , ' status ' ] , stderr = subprocess . STDOUT , stdout = open ( os . devnull , ' w ' ) ) == 0
def workspace_manager ( ) :
branch = subprocess . getoutput ( " git rev-parse --abbrev-ref HEAD " )
if branch == " master " :
branch = " default "
2019-04-17 10:53:05 +02:00
else :
2019-04-17 11:44:14 +02:00
if branch not in get_valid_envs ( ) :
branch = " qa "
if get_env ( ) != branch :
print ( " [INFO]: Terraform workspace & git branch have diverged. Changing workspace to git branch... " )
subprocess . call ( [ " terraform " , " workspace " , " new " , branch ] , stderr = subprocess . STDOUT , stdout = open ( os . devnull , ' w ' ) )
subprocess . call ( [ " terraform " , " workspace " , " select " , branch ] , stderr = subprocess . STDOUT , stdout = open ( os . devnull , ' w ' ) )
2019-04-17 10:53:05 +02:00
2019-04-15 15:15:39 +02:00
def generate_creds ( ) :
current_workspace = get_env ( )
workspaces = [ ' default ' ]
if current_workspace != ' default ' :
workspaces . append ( current_workspace )
contents = " "
for workspace in workspaces :
contents = contents + " [ {workspace} ] \n " . format ( workspace = workspace )
2019-04-15 16:38:32 +02:00
contents = contents + " aws_access_key_id= " + os . environ . get ( workspace . upper ( ) + ' _ACCESS_KEY_ID ' ) + " \n "
contents = contents + " aws_secret_access_key= " + os . environ . get ( workspace . upper ( ) + ' _SECRET_ACCESS_KEY ' ) + " \n "
2019-07-16 17:12:34 +02:00
with open ( os . path . expanduser ( ' ~/.aws/credentials-atmos ' ) , ' w+ ' ) as f :
2019-04-15 15:15:39 +02:00
f . write ( contents )
2019-04-10 12:00:01 +02:00
def get_valid_envs ( ) :
try :
2019-04-10 13:47:03 +02:00
# Use var files when present, otherwise default to qa
return [ os . path . splitext ( os . path . basename ( x ) ) [ 0 ] for x in glob . glob ( " vars/*.tfvars " ) ]
2019-04-10 12:00:01 +02:00
except FileNotFoundError :
return False
2019-04-09 16:54:28 +02:00
def get_env ( ) :
2019-04-10 13:47:03 +02:00
try :
tf_env = open ( ' .terraform/environment ' , ' r ' ) . read ( )
except :
2019-04-15 15:15:39 +02:00
return ( " default " )
2019-04-10 12:00:01 +02:00
if str ( tf_env ) in get_valid_envs ( ) :
2019-04-09 16:54:28 +02:00
return ( tf_env )
else :
return ( " qa " )
if __name__ == " __main__ " :
main ( sys . argv )