diff --git a/terrabutler/env.py b/terrabutler/env.py index c78ed10..c26b0d6 100644 --- a/terrabutler/env.py +++ b/terrabutler/env.py @@ -1,18 +1,15 @@ from terrabutler.settings import get_settings from terrabutler.tf import terraform_init_all_sites +from terrabutler.utils import paths from click import confirm from colorama import Fore import boto3 import os import subprocess -# Values from Config -backend_dir = os.path.realpath(get_settings()["locations"]["backend_dir"]) -environment_file = os.path.realpath(get_settings() - ["locations"]["environment_file"]) -inception_dir = os.path.realpath(get_settings()["locations"]["inception_dir"]) -templates_dir = os.path.realpath(get_settings()["locations"]["templates_dir"]) -variables_dir = os.path.realpath(get_settings()["locations"]["variables_dir"]) +# Values from Settings +org = get_settings()["general"]["organization"] +default_env_name = get_settings()["environments"]["default"]["name"] def create_env(env, confirmation, temporary, apply, s3): @@ -29,7 +26,7 @@ def create_env(env, confirmation, temporary, apply, s3): " environment?", default=False): try: subprocess.run(args=['terraform', 'workspace', 'new', env], - cwd=inception_dir, stdout=subprocess.DEVNULL, + cwd=paths["inception"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True) except subprocess.CalledProcessError: print(Fore.RED + "There was an error while creating the new" @@ -55,7 +52,6 @@ def delete_env(env, confirmation, destroy, s3): from terrabutler.tf import terraform_destroy_all_sites available_envs = get_available_envs(s3) current_env = get_current_env() - org = get_settings()["general"]["organization"] permanent_environments = get_settings()["environments"]["permanent"] if env not in available_envs: @@ -76,12 +72,12 @@ def delete_env(env, confirmation, destroy, s3): " environment?", default=False): if destroy and not is_protected_env(env): terraform_destroy_all_sites() # Destroy all sites - for file in os.listdir(variables_dir): + for file in os.listdir(paths["variables"]): if file.startswith(f"{org}-{env}"): - os.remove(os.path.join(variables_dir, file)) + os.remove(os.path.join(paths["variables"], file)) try: subprocess.run(args=['terraform', 'workspace', 'delete', env], - cwd=inception_dir, stdout=subprocess.DEVNULL, + cwd=paths["inception"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True) except subprocess.CalledProcessError: print(Fore.RED + f"There was an error while deleting the '{env}'" @@ -94,7 +90,7 @@ def delete_env(env, confirmation, destroy, s3): def get_current_env(): - with open(environment_file, 'r') as f: + with open(paths["environment"], 'r') as f: return f.read() @@ -112,7 +108,7 @@ def set_current_env(env, s3): exit(1) else: try: - with open(environment_file, "w") as f: + with open(paths["environment"], "w") as f: f.write(env) except FileNotFoundError: print(Fore.RED + "The file that manages the environments could not" @@ -130,9 +126,10 @@ def get_available_envs(s3): # Get Environments by accessing S3 if s3: - dev_env = boto3.session.Session(profile_name="pl-dev") + dev_env = boto3.session.Session(profile_name=f"{org}" + f"-{default_env_name}") s3 = dev_env.resource("s3") - bucket = s3.Bucket("pl-dev-site-inception-tfstate") + bucket = s3.Bucket(f"{org}-{default_env_name}-site-inception-tfstate") envs = [] @@ -143,10 +140,11 @@ def get_available_envs(s3): return envs # Get Environments by accessing the .terraform/environment file - directory = inception_dir + directory = paths["inception"] subprocess.run(args=["terraform", "init", "-reconfigure", "-backend-config", - f"{environment_file}/pl-dev-inception.tfvars"], + f"{paths['backends']}/{org}-{default_env_name}-" + "inception.tfvars"], cwd=directory, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) diff --git a/terrabutler/inception.py b/terrabutler/inception.py index 8394842..59de398 100644 --- a/terrabutler/inception.py +++ b/terrabutler/inception.py @@ -1,13 +1,14 @@ +from terrabutler.utils import paths from colorama import Fore from os import path import subprocess def inception_init_check(): - site_dir = path.realpath("site_inception") + dir = paths["inception"] - if (path.exists(f"{site_dir}/.terraform") and - path.exists(f"{site_dir}/.terraform/environment")): + if (path.exists(f"{dir}/.terraform") and + path.exists(f"{dir}/.terraform/environment")): return True return False @@ -23,21 +24,24 @@ def inception_init_needed(): def inception_init(): from terrabutler.env import reload_direnv from terrabutler.settings import get_settings - site_dir = path.realpath(get_settings()["locations"]["inception_dir"]) - backend_dir = path.realpath(get_settings()["locations"]["backend_dir"]) + org = get_settings()["general"]["organization"] + default_env_name = get_settings()["environments"]["default"]["name"] + inception_dir = paths["inception"] + backend_dir = paths["backends"] if not inception_init_check(): try: subprocess.run(args=["terraform", "init", "-backend-config", - f"{backend_dir}/pl-dev-inception.tfvars"], - cwd=site_dir, stdout=subprocess.DEVNULL, + f"{backend_dir}/{org}-{default_env_name}" + "-inception.tfvars"], + cwd=inception_dir, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) except subprocess.CalledProcessError: print(Fore.RED + "There was an error while doing the initializing") exit(1) try: - with open(f"{site_dir}/.terraform/environment", "w") as f: + with open(f"{inception_dir}/.terraform/environment", "w") as f: f.write("dev") except FileNotFoundError: print(Fore.RED + "The file that manages the environments could not" diff --git a/terrabutler/settings.py b/terrabutler/settings.py index c1cc609..30c406e 100644 --- a/terrabutler/settings.py +++ b/terrabutler/settings.py @@ -1,27 +1,22 @@ +from terrabutler import paths from colorama import Fore -from os import getenv, path +from os import path from schema import Schema, SchemaError import yaml -PATH = path.realpath(getenv("TERRABUTLER_ROOT") + "configs/settings.yml") +PATH = paths["settings"] SCHEMA = Schema({ "general": { "organization": str, "secrets_key_id": str }, - "locations": { - "backend_dir": str, - "environment_file": str, - "inception_dir": str, - "templates_dir": str, - "variables_dir": str - }, "sites": { "ordered": list }, "environments": { "default": { "domain": str, + "name": str, "profile_name": str, "region": str }, diff --git a/terrabutler/tf.py b/terrabutler/tf.py index d2c1f37..8b86562 100644 --- a/terrabutler/tf.py +++ b/terrabutler/tf.py @@ -3,14 +3,10 @@ import subprocess from colorama import Fore from terrabutler.settings import get_settings +from terrabutler.utils import paths # Values from Config -backend_dir = os.path.realpath(get_settings()["locations"]["backend_dir"]) -environment_file = os.path.realpath(get_settings() - ["locations"]["environment_file"]) -inception_dir = os.path.realpath(get_settings()["locations"]["inception_dir"]) -templates_dir = os.path.realpath(get_settings()["locations"]["templates_dir"]) -variables_dir = os.path.realpath(get_settings()["locations"]["variables_dir"]) +org = get_settings()["general"]["organization"] def setup_tfenv(site): @@ -36,8 +32,8 @@ def terraform_args_print(command, site): elif command == "plan" or command == "apply": needed_args = "var" - args = terraform_args_builder(needed_args, site, backend_dir, - variables_dir) + args = terraform_args_builder(needed_args, site, paths["backends"], + paths["variables"]) return " ".join(args) @@ -51,15 +47,15 @@ def terraform_args_builder(needed_args, site, backend_dir, var_dir): if needed_args == "backend": if site == "inception": return ["-backend-config", - f"{backend_dir}/pl-dev-inception.tfvars"] + f"{backend_dir}/{org}-dev-inception.tfvars"] else: return ["-backend-config", - f"{backend_dir}/pl-{env}-{site}.tfvars"] + f"{backend_dir}/{org}-{env}-{site}.tfvars"] elif needed_args == "var": - return ["-var-file", f"{variables_dir}/global.tfvars", - "-var-file", f"{variables_dir}/pl-{env}.tfvars", - "-var-file", f"{variables_dir}/pl-{env}-{site}.tfvars" + return ["-var-file", f"{paths['variables']}/global.tfvars", + "-var-file", f"{paths['variables']}/{org}-{env}.tfvars", + "-var-file", f"{paths['variables']}/{org}-{env}-{site}.tfvars" ] return [] @@ -90,7 +86,7 @@ def terraform_command_runner(command, args, needed_args, site): setup_tfenv(site_dir) command = terraform_command_builder(command, args, needed_args, site, - backend_dir, variables_dir) + paths["backends"], paths["variables"]) try: p = subprocess.Popen(args=command, cwd=site_dir) p.wait() diff --git a/terrabutler/utils.py b/terrabutler/utils.py new file mode 100644 index 0000000..0901eb9 --- /dev/null +++ b/terrabutler/utils.py @@ -0,0 +1,13 @@ +from os import getenv + +ROOT_PATH = getenv("TERRABUTLER_ROOT") + +paths = { + "backends": ROOT_PATH + "/configs/backends", + "environment": ROOT_PATH + "/site_inception/.terraform/environment", + "inception": ROOT_PATH + "/site_inception", + "root": ROOT_PATH, + "settings": ROOT_PATH + "configs/settings.yml", + "templates": ROOT_PATH + "/configs/templates", + "variables": ROOT_PATH + "/configs/variables" +} diff --git a/terrabutler/variables.py b/terrabutler/variables.py index 745f7bf..bb8e70d 100644 --- a/terrabutler/variables.py +++ b/terrabutler/variables.py @@ -1,7 +1,4 @@ -from os import ( - listdir, - path -) +from os import listdir import boto3 from base64 import b64encode from jinja2 import ( @@ -14,11 +11,10 @@ digits ) from terrabutler.settings import get_settings +from terrabutler.utils import paths REGION = get_settings()["environments"]["default"]["region"] -TEMPLATES_DIR = path.realpath(get_settings()["locations"]["templates_dir"]) -VARIABLES_DIR = path.realpath(get_settings()["locations"]["variables_dir"]) ORG = get_settings()["general"]["organization"] KEY_ID = get_settings()["general"]["secrets_key_id"] @@ -27,8 +23,8 @@ def generate_var_files(env): """ Create a variables files for a given environment """ - templates = listdir(TEMPLATES_DIR) - file_loader = FileSystemLoader(TEMPLATES_DIR) + templates = listdir(paths["templates"]) + file_loader = FileSystemLoader(paths["templates"]) environment = Environment(loader=file_loader) sites = list(get_settings()["sites"]["ordered"]) firebase_credentials = (get_settings()["environments"]["temporary"] @@ -48,10 +44,11 @@ def generate_var_files(env): firebase_credentials=firebase_credentials) name = template.replace(".j2", "") if name == 'env': - with open(f"{VARIABLES_DIR}/{ORG}-{env}.tfvars", "w") as fh: + with open(f"{paths['variables']}/{ORG}-{env}.tfvars", "w") as fh: fh.write(output) else: - with open(f"{VARIABLES_DIR}/{ORG}-{env}-{name}.tfvars", "w")as fh: + with open(f"{paths['variables']}/{ORG}-{env}-{name}" + ".tfvars", "w") as fh: fh.write(output) @@ -68,7 +65,7 @@ def encrypt_password(password): """ Encrypt password with AWS KMS """ - environment = boto3.session.Session(profile_name="pl-dev", + environment = boto3.session.Session(profile_name=f"{ORG}-dev", region_name=REGION) kms = environment.client("kms") encrypted = kms.encrypt(KeyId=KEY_ID, Plaintext=password)