diff --git a/terraform/secrets-tool/commands/terraform.py b/terraform/secrets-tool/commands/terraform.py index f34db59d..8fcdf55a 100644 --- a/terraform/secrets-tool/commands/terraform.py +++ b/terraform/secrets-tool/commands/terraform.py @@ -4,64 +4,48 @@ import logging import subprocess from utils.keyvault.secrets import SecretsClient +from utils.terraform.wrapper import TFWrapper logger = logging.getLogger(__name__) PROCESS='terraform' @click.group() +@click.option('--keyvault', required=True, help="Specify the keyvault to operate on") @click.pass_context -def terraform(ctx): - pass +def terraform(ctx, keyvault): + ctx.ensure_object(dict) + ctx.obj['keyvault'] = keyvault @click.command('plan') @click.pass_context def plan(ctx): - keyvault = SecretsClient(vault_url="https://cloudzero-dev-keyvault.vault.azure.net/") - # Set env variables for TF - for secret in keyvault.list_secrets(): - name = 'TF_VAR_' + secret - val = keyvault.get_secret(secret) - #print(val) - os.environ[name] = val - env = os.environ.copy() - command = "{} {}".format(PROCESS, 'plan') - with subprocess.Popen(command, env=env, stdout=subprocess.PIPE, shell=True) as proc: - for line in proc.stdout: - logging.info(line.decode("utf-8") ) + keyvault = SecretsClient(vault_url=ctx.obj['keyvault']) + tf = TFWrapper(keyvault) + tf.plan() @click.command('apply') @click.pass_context def apply(ctx): - keyvault = SecretsClient(vault_url="https://cloudzero-dev-keyvault.vault.azure.net/") - # Set env variables for TF - for secret in keyvault.list_secrets(): - name = 'TF_VAR_' + secret - val = keyvault.get_secret(secret) - #print(val) - os.environ[name] = val - env = os.environ.copy() - command = "{} {}".format(PROCESS, 'apply -auto-approve') - with subprocess.Popen(command, env=env, stdout=subprocess.PIPE, shell=True) as proc: - for line in proc.stdout: - logging.info(line.decode("utf-8") ) + keyvault = SecretsClient(vault_url=ctx.obj['keyvault']) + tf = TFWrapper(keyvault) + tf.apply() @click.command('destroy') @click.pass_context def destroy(ctx): - keyvault = SecretsClient(vault_url="https://cloudzero-dev-keyvault.vault.azure.net/") - # Set env variables for TF - for secret in keyvault.list_secrets(): - name = 'TF_VAR_' + secret - val = keyvault.get_secret(secret) - #print(val) - os.environ[name] = val - env = os.environ.copy() - command = "{} {}".format(PROCESS, 'destroy') - with subprocess.Popen(command, env=env, stdout=subprocess.PIPE, shell=True) as proc: - for line in proc.stdout: - logging.info(line.decode("utf-8") ) + keyvault = SecretsClient(vault_url=ctx.obj['keyvault']) + tf = TFWrapper(keyvault) + tf.destroy() + +@click.command('init') +@click.pass_context +def init(ctx): + keyvault = SecretsClient(vault_url=ctx.obj['keyvault']) + tf = TFWrapper(keyvault) + tf.init() terraform.add_command(plan) terraform.add_command(apply) -terraform.add_command(destroy) \ No newline at end of file +terraform.add_command(destroy) +terraform.add_command(init) \ No newline at end of file diff --git a/terraform/secrets-tool/logging.yaml b/terraform/secrets-tool/logging.yaml index 3aaf1619..3e31ffd4 100644 --- a/terraform/secrets-tool/logging.yaml +++ b/terraform/secrets-tool/logging.yaml @@ -49,6 +49,10 @@ loggers: level: DEBUG handlers: [console] propogate: yes + utils.terraform.wrapper: + level: DEBUG + handlers: [console] + propogate: yes commands: level: INFO handlers: [console] diff --git a/terraform/secrets-tool/utils/terraform/__init__.py b/terraform/secrets-tool/utils/terraform/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/terraform/secrets-tool/utils/terraform/wrapper.py b/terraform/secrets-tool/utils/terraform/wrapper.py new file mode 100644 index 00000000..96d44396 --- /dev/null +++ b/terraform/secrets-tool/utils/terraform/wrapper.py @@ -0,0 +1,61 @@ +import os +import logging +import subprocess + +logger = logging.getLogger(__name__) + +class TFWrapper: + """ + Command wrapper for terraform that injects secrets + from keyvault in to environment variables which + can then be used by terraform + """ + def __init__(self, keyvault: object): + self.keyvault = keyvault + self.env = '' + self.terraform_path = 'terraform' + + self._set_env() + + def _set_env(self): + # Prefix variables with TF_VAR_ + for secret in self.keyvault.list_secrets(): + name = 'TF_VAR_' + secret + val = self.keyvault.get_secret(secret) + os.environ[name] = val + # Set the environment with new vars + self.env = os.environ.copy() + return None + + def _run_tf(self, option: str): + try: + command = '{} {}'.format(self.terraform_path, option) + with subprocess.Popen(command, env=self.env, stdout=subprocess.PIPE, shell=True) as proc: + for line in proc.stdout: + logging.info(line.decode("utf-8")) + except Exception as e: + print(e) + + def plan(self): + """ + terraform plan + """ + self._run_tf(option='plan') + + def init(self): + """ + terraform init + """ + self._run_tf(option='init') + + def apply(self): + """ + terraform apply + """ + self._run_tf(option='apply -auto-approve') + + def destroy(self): + """ + terraform destroy + """ + self._run_tf(option='destroy') \ No newline at end of file