diff --git a/build.py b/build.py index d147c7e..d2b04e2 100644 --- a/build.py +++ b/build.py @@ -28,7 +28,7 @@ use_plugin("python.distutils") default_task = "publish" name = "ddadevops" -version = "0.4.2.dev11" +version = "0.4.2.dev27" summary = "tools to support builds combining gopass, terraform, dda-pallet, aws & hetzner-cloud" description = __doc__ authors = [Author("meissa GmbH", "buero@meissa-gmbh.de")] diff --git a/src/main/python/ddadevops/__init__.py b/src/main/python/ddadevops/__init__.py index 62ddb46..d711bf3 100644 --- a/src/main/python/ddadevops/__init__.py +++ b/src/main/python/ddadevops/__init__.py @@ -6,7 +6,7 @@ terraform, dda-pallet, aws & hetzner-cloud. from .credential import gopass_credential_from_env_path, gopass_credential_from_path from .devops_build import DevopsBuild, create_devops_build_config, get_devops_build -from .devops_terraform_build import DevopsTerraformBuild, create_devops_terraform_build_config +from .devops_terraform_build import WorkaroundTerraform, DevopsTerraformBuild, create_devops_terraform_build_config from .hetzner_mixin import HetznerMixin, add_hetzner_mixin_config from .aws_backend_properties_mixin import AwsBackendPropertiesMixin, add_aws_backend_properties_mixin_config from .aws_mfa_mixin import AwsMfaMixin, add_aws_mfa_mixin_config diff --git a/src/main/python/ddadevops/aws_backend_properties_mixin.py b/src/main/python/ddadevops/aws_backend_properties_mixin.py index f8ecc51..ad4ac5f 100644 --- a/src/main/python/ddadevops/aws_backend_properties_mixin.py +++ b/src/main/python/ddadevops/aws_backend_properties_mixin.py @@ -1,5 +1,5 @@ from python_terraform import * -from .devops_terraform_build import DevopsTerraformBuild +from .devops_terraform_build import DevopsTerraformBuild, WorkaroundTerraform def add_aws_backend_properties_mixin_config(config, account_name): @@ -14,7 +14,7 @@ class AwsBackendPropertiesMixin(DevopsTerraformBuild): super().__init__(project, config) aws_mixin_config = config['AwsBackendPropertiesMixin'] self.account_name = aws_mixin_config['account_name'] - + def backend_config(self): return "backend." + self.account_name + "." + self.stage + ".properties" @@ -26,35 +26,48 @@ class AwsBackendPropertiesMixin(DevopsTerraformBuild): def copy_build_resources_from_package(self): super().copy_build_resources_from_package() self.copy_build_resource_file_from_package('aws_provider.tf') - self.copy_build_resource_file_from_package('aws_backend_properties_vars.tf') - self.copy_build_resource_file_from_package('aws_backend_with_properties.tf') + self.copy_build_resource_file_from_package( + 'aws_backend_properties_vars.tf') + self.copy_build_resource_file_from_package( + 'aws_backend_with_properties.tf') def init_client(self): - tf = Terraform(working_dir=self.build_path()) - self.print_terraform_command('init --backend-config=' + self.backend_config()) + tf = WorkaroundTerraform(working_dir=self.build_path()) tf.init(backend_config=self.backend_config()) + self.print_terraform_command(tf) if self.use_workspace: try: tf.workspace('select', slef.stage) + self.print_terraform_command(tf) except: tf.workspace('new', self.stage) + self.print_terraform_command(tf) return tf def plan(self): tf = self.init_client() - self.print_terraform_command('plan --var-file=' + self.backend_config()) - tf.plan(capture_output=False, var=self.project_vars(), + tf.plan(capture_output=False, raise_on_error=True, + var=self.project_vars(), var_file=self.backend_config()) + self.print_terraform_command(tf) - def apply(self, p_auto_approve=False): + def apply(self, auto_approve=False): tf = self.init_client() - self.print_terraform_command('apply --var-file=' + self.backend_config()) - tf.apply(capture_output=False, auto_approve=p_auto_approve, - var=self.project_vars(), var_file=self.backend_config()) + tf.apply(capture_output=False, raise_on_error=True, + skip_plan=auto_approve, + var=self.project_vars(), + var_file=self.backend_config()) + self.print_terraform_command(tf) self.write_output(tf) - def destroy(self, p_auto_approve=False): + def destroy(self, auto_approve=False): tf = self.init_client() - self.print_terraform_command('destroy --var-file=' + self.backend_config()) - tf.destroy(capture_output=False, auto_approve=p_auto_approve, - var=self.project_vars(), var_file=self.backend_config()) + if auto_approve: + force = IsFlagged + else: + force = None + tf.destroy(capture_output=False, raise_on_error=True, + force=force, + var=self.project_vars(), + var_file=self.backend_config()) + self.print_terraform_command(tf) diff --git a/src/main/python/ddadevops/devops_terraform_build.py b/src/main/python/ddadevops/devops_terraform_build.py index acb9928..7bd21ed 100644 --- a/src/main/python/ddadevops/devops_terraform_build.py +++ b/src/main/python/ddadevops/devops_terraform_build.py @@ -25,7 +25,21 @@ def create_devops_terraform_build_config(stage, project_root_path, build_commons 'debug_print_terraform_command': debug_print_terraform_command}) return ret + class WorkaroundTerraform(Terraform): + def __init__(self, working_dir=None, + targets=None, + state=None, + variables=None, + parallelism=None, + var_file=None, + terraform_bin_path=None, + is_env_vars_included=True, + ): + super().__init__(working_dir, targets, state, variables, parallelism, + var_file, terraform_bin_path, is_env_vars_included) + self.latest_cmd = '' + def apply(self, dir_or_plan=None, input=False, skip_plan=False, no_color=IsFlagged, **kwargs): """ @@ -41,17 +55,18 @@ class WorkaroundTerraform(Terraform): default = kwargs default['input'] = input default['no_color'] = no_color + if skip_plan: + default['auto-approve'] = IsFlagged + else: + default['auto-approve'] = None option_dict = self._generate_default_options(default) - default['auto-approve'] = (skip_plan == True) args = self._generate_default_args(dir_or_plan) return self.cmd('apply', *args, **option_dict) def generate_cmd_string(self, cmd, *args, **kwargs): - self.latest_cmd = super().generate_cmd_string(self, cmd, *args, **kwargs) - return self.latest_cmd - - def latest_cmd(self): - return self.latest_cmd + result = super().generate_cmd_string(cmd, *args, **kwargs) + self.latest_cmd = ' '.join(result) + return result class DevopsTerraformBuild(DevopsBuild): @@ -78,9 +93,10 @@ class DevopsTerraformBuild(DevopsBuild): if self.additional_vars: ret.update(self.additional_vars) return ret - + def copy_build_resource_file_from_package(self, name): - my_data = resource_string(__name__, "src/main/resources/terraform/" + name) + my_data = resource_string( + __name__, "src/main/resources/terraform/" + name) with open(self.build_path() + '/' + name, "w") as output_file: output_file.write(my_data.decode(sys.stdout.encoding)) @@ -127,24 +143,27 @@ class DevopsTerraformBuild(DevopsBuild): def plan(self): tf = self.init_client() - tf.plan(capture_output=False, raise_on_error=True, var=self.project_vars()) + tf.plan(capture_output=False, raise_on_error=True, + var=self.project_vars()) self.print_terraform_command(tf) def apply(self, auto_approve=False): tf = self.init_client() - tf.apply(capture_output=False, raise_on_error=True, skip_plan=auto_approve, - var=self.project_vars()) + tf.apply(capture_output=False, raise_on_error=True, + skip_plan=auto_approve, + var=self.project_vars()) self.print_terraform_command(tf) self.write_output(tf) def destroy(self, auto_approve=False): tf = self.init_client() if auto_approve: - force=IsFlagged + force = IsFlagged else: - force=None - tf.destroy(capture_output=False, raise_on_error=True, force=force, - var=self.project_vars()) + force = None + tf.destroy(capture_output=False, raise_on_error=True, + force=force, + var=self.project_vars()) self.print_terraform_command(tf) def tf_import(self, tf_import_name, tf_import_resource,): @@ -155,5 +174,5 @@ class DevopsTerraformBuild(DevopsBuild): def print_terraform_command(self, tf): if self.debug_print_terraform_command: - output = 'cd ' + self.build_path() + ' ' + tf.latest_cmd() + output = 'cd ' + self.build_path() + ' && ' + tf.latest_cmd print(output)