diff --git a/CHANGES.md b/CHANGES.md index 494633f..1a6149d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,6 @@ # Change Log +## 2.1.0 +* Added: 'env_variable_dict' dedicated for sensitive environment variables ## 2.0.2 * Fixed: removed 'os.chdir' calls that were causing os.chdir errors diff --git a/actions/apply.py b/actions/apply.py index f835c72..82f5dea 100644 --- a/actions/apply.py +++ b/actions/apply.py @@ -4,7 +4,7 @@ class Apply(action.TerraformBaseAction): def run(self, plan_path, state_file_path, target_resources, terraform_exec, - variable_dict, variable_files): + variable_dict, variable_files, env_variable_dict): """ Apply the changes required to reach the desired state of the configuration. @@ -16,10 +16,12 @@ def run(self, plan_path, state_file_path, target_resources, terraform_exec, - variable_dict: dictionary of Terraform variables that will overwrite the variable files if both are declared - variable_files: array of Terraform variable files + - env_variable_dict: array dedicated for sensitive environment variables Returns: - dict: Terraform output command output """ + self.set_env_variable_dict(env_variable_dict) self.terraform.working_dir = plan_path self.terraform.state = state_file_path self.terraform.targets = target_resources diff --git a/actions/apply.yaml b/actions/apply.yaml index 6b66c72..650253b 100644 --- a/actions/apply.yaml +++ b/actions/apply.yaml @@ -30,3 +30,8 @@ parameters: type: "array" description: "Terraform variable files" required: false + env_variable_dict: + type: "object" + description: "Key-Value pairs of sensitive environment variables." + required: false + secret: true diff --git a/actions/destroy.py b/actions/destroy.py index a169e17..1c971a5 100644 --- a/actions/destroy.py +++ b/actions/destroy.py @@ -4,7 +4,7 @@ class Destroy(action.TerraformBaseAction): def run(self, plan_path, state_file_path, target_resources, terraform_exec, - variable_dict, variable_files): + variable_dict, variable_files, env_variable_dict): """ Destroy Terraform managed infrastructure @@ -16,10 +16,12 @@ def run(self, plan_path, state_file_path, target_resources, terraform_exec, - variable_dict: dictionary of Terraform variables that will overwrite the variable files if both are declared - variable_files: array of Terraform variable files + - env_variable_dict: array dedicated for sensitive environment variables Returns: - dict: Terraform destroy command output """ + self.set_env_variable_dict(env_variable_dict) self.terraform.working_dir = plan_path self.terraform.terraform_bin_path = terraform_exec self.set_semantic_version() diff --git a/actions/destroy.yaml b/actions/destroy.yaml index cae177b..cbba403 100644 --- a/actions/destroy.yaml +++ b/actions/destroy.yaml @@ -30,3 +30,8 @@ parameters: type: "array" description: "Terraform variable files" required: false + env_variable_dict: + type: "object" + description: "Key-Value pairs of sensitive environment variables." + required: false + secret: true diff --git a/actions/init.py b/actions/init.py index a3b6c7c..e7d8800 100644 --- a/actions/init.py +++ b/actions/init.py @@ -3,7 +3,7 @@ class Init(action.TerraformBaseAction): - def run(self, plan_path, terraform_exec, backend, upgrade): + def run(self, plan_path, terraform_exec, backend, upgrade, env_variable_dict): """ Initialize a working directory containing Terraform configuration files @@ -12,10 +12,12 @@ def run(self, plan_path, terraform_exec, backend, upgrade): - terraform_exec: path of the Terraform bin - backend: backend configuration variable file - upgrade: Run init with -upgrade option + - env_variable_dict: array dedicated for sensitive environment variables Returns: - dict: Terraform init command output """ + self.set_env_variable_dict(env_variable_dict) self.terraform.working_dir = plan_path self.terraform.terraform_bin_path = terraform_exec self.set_semantic_version() diff --git a/actions/init.yaml b/actions/init.yaml index 98d1fee..a8a5d85 100644 --- a/actions/init.yaml +++ b/actions/init.yaml @@ -22,3 +22,8 @@ parameters: type: "boolean" description: "Run init with -upgrade option" required: false + env_variable_dict: + type: "object" + description: "Key-Value pairs of sensitive environment variables." + required: false + secret: true diff --git a/actions/lib/action.py b/actions/lib/action.py index db27e1e..4b4706a 100644 --- a/actions/lib/action.py +++ b/actions/lib/action.py @@ -1,6 +1,7 @@ from st2common.runners.base_action import Action from dda_python_terraform import Terraform import json +import os class TerraformBaseAction(Action): @@ -70,3 +71,13 @@ def concat_std_output(stdout, stderr): output += stderr return output + + def set_env_variable_dict(self, env_variable_dict=None): + try: + if env_variable_dict: + for env_var_name in env_variable_dict.keys(): + value = str(env_variable_dict.get(env_var_name)) + os.environ[str(env_var_name)] = f"{value}" + return True + except: + return False diff --git a/actions/plan.py b/actions/plan.py index 74418fd..680fb56 100644 --- a/actions/plan.py +++ b/actions/plan.py @@ -3,7 +3,7 @@ class Plan(action.TerraformBaseAction): def run(self, plan_path, state_file_path, target_resources, terraform_exec, - variable_dict, variable_files): + variable_dict, variable_files, env_variable_dict): """ Plan the changes required to reach the desired state of the configuration @@ -15,10 +15,12 @@ def run(self, plan_path, state_file_path, target_resources, terraform_exec, - variable_dict: dictionary of Terraform variables that will overwrite the variable files if both are declared - variable_files: array of Terraform variable files + - env_variable_dict: array dedicated for sensitive environment variables Returns: - dict: Terraform output command output """ + self.set_env_variable_dict(env_variable_dict) self.terraform.working_dir = plan_path self.terraform.state = state_file_path self.terraform.targets = target_resources diff --git a/actions/plan.yaml b/actions/plan.yaml index 8876d87..1661495 100644 --- a/actions/plan.yaml +++ b/actions/plan.yaml @@ -30,3 +30,8 @@ parameters: type: "array" description: "Terraform variable files" required: false + env_variable_dict: + type: "object" + description: "Key-Value pairs of sensitive environment variables." + required: false + secret: true diff --git a/pack.yaml b/pack.yaml index 6baee25..eaff97d 100644 --- a/pack.yaml +++ b/pack.yaml @@ -5,7 +5,7 @@ runner_type: "python-script" description: Terraform integrations keywords: - terraform -version: 2.0.2 +version: 2.1.0 author: Martez Reed email: martez.reed@greenreedtech.com python_versions: diff --git a/tests/test_action_apply.py b/tests/test_action_apply.py index e77857f..56dea1e 100644 --- a/tests/test_action_apply.py +++ b/tests/test_action_apply.py @@ -24,6 +24,7 @@ def test_run(self, mock_apply, mock_check_result, mock_version): test_terraform_exec = "/usr/bin/terraform" test_variable_dict = {'key1': 'value1', 'key2': 'value2'} test_variable_files = ["/terraform/test.tfvars"] + test_env_variable_dict = {'key1': 'value1', 'key2': 'value2'} # Declare test Terraform.plan return values test_return_code = 0 @@ -38,7 +39,8 @@ def test_run(self, mock_apply, mock_check_result, mock_version): # Execute the run function result = action.run(test_plan_path, test_state_file, test_target_resources, - test_terraform_exec, test_variable_dict, test_variable_files) + test_terraform_exec, test_variable_dict, test_variable_files, + test_env_variable_dict) # Verify the results self.assertEqual(result, expected_result) @@ -47,6 +49,7 @@ def test_run(self, mock_apply, mock_check_result, mock_version): self.assertEqual(action.terraform.terraform_bin_path, test_terraform_exec) self.assertEqual(action.terraform.var_file, test_variable_files) self.assertEqual(action.terraform.variables, test_variable_dict) + self.assertEqual(action.set_env_variable_dict(test_env_variable_dict), True) mock_apply.assert_called_with( skip_plan=True, auto_approve=IsFlagged, diff --git a/tests/test_action_destroy.py b/tests/test_action_destroy.py index 853e342..20bdb9d 100644 --- a/tests/test_action_destroy.py +++ b/tests/test_action_destroy.py @@ -24,6 +24,7 @@ def test_run(self, mock_destroy, mock_check_result, mock_version): test_terraform_exec = "/usr/bin/terraform" test_variable_dict = {'key1': 'value1', 'key2': 'value2'} test_variable_files = ["/terraform/test.tfvars"] + test_env_variable_dict = {'key1': 'value1', 'key2': 'value2'} # Declare test Terraform.plan return values test_return_code = 0 @@ -38,12 +39,14 @@ def test_run(self, mock_destroy, mock_check_result, mock_version): # Execute the run function result = action.run(test_plan_path, test_state_file, test_target_resources, - test_terraform_exec, test_variable_dict, test_variable_files) + test_terraform_exec, test_variable_dict, test_variable_files, + test_env_variable_dict) # Verify the results self.assertEqual(result, expected_result) self.assertEqual(action.terraform.targets, test_target_resources) self.assertEqual(action.terraform.terraform_bin_path, test_terraform_exec) + self.assertEqual(action.set_env_variable_dict(test_env_variable_dict), True) mock_destroy.assert_called_with( var_file=test_variable_files, var=test_variable_dict, diff --git a/tests/test_action_init.py b/tests/test_action_init.py index efac2fc..b401337 100644 --- a/tests/test_action_init.py +++ b/tests/test_action_init.py @@ -22,6 +22,7 @@ def test_run_upgrade_false(self, mock_init, mock_check_result, mock_version): test_terraform_exec = "/usr/bin/terraform" test_backend = {'path': '/terraform/terraform.tfstate'} test_upgrade = False + test_env_variable_dict = {'key1': 'value1', 'key2': 'value2'} # Declare test Terraform.init return values test_return_code = 0 @@ -35,11 +36,13 @@ def test_run_upgrade_false(self, mock_init, mock_check_result, mock_version): mock_check_result.return_value = expected_result # Execute the run function - result = action.run(test_plan_path, test_terraform_exec, test_backend, test_upgrade) + result = action.run(test_plan_path, test_terraform_exec, test_backend, test_upgrade, + test_env_variable_dict) # Verify the results self.assertEqual(result, expected_result) self.assertEqual(action.terraform.terraform_bin_path, test_terraform_exec) + self.assertEqual(action.set_env_variable_dict(test_env_variable_dict), True) mock_init.assert_called_with( backend_config=test_backend, capture_output=False, @@ -57,6 +60,7 @@ def test_run_upgrade_true(self, mock_init, mock_check_result, mock_version): test_plan_path = "/terraform" test_terraform_exec = "/usr/bin/terraform" test_backend = {'path': '/terraform/terraform.tfstate'} + test_env_variable_dict = {'key1': 'value1', 'key2': 'value2'} test_upgrade = True # Declare test Terraform.init return values @@ -71,11 +75,13 @@ def test_run_upgrade_true(self, mock_init, mock_check_result, mock_version): mock_check_result.return_value = expected_result # Execute the run function - result = action.run(test_plan_path, test_terraform_exec, test_backend, test_upgrade) + result = action.run(test_plan_path, test_terraform_exec, test_backend, test_upgrade, + test_env_variable_dict) # Verify the results self.assertEqual(result, expected_result) self.assertEqual(action.terraform.terraform_bin_path, test_terraform_exec) + self.assertEqual(action.set_env_variable_dict(test_env_variable_dict), True) mock_init.assert_called_with( backend_config=test_backend, capture_output=False, @@ -93,6 +99,7 @@ def test_run_upgrade_none(self, mock_init, mock_check_result, mock_version): test_plan_path = "/terraform" test_terraform_exec = "/usr/bin/terraform" test_backend = {'path': '/terraform/terraform.tfstate'} + test_env_variable_dict = {'key1': 'value1', 'key2': 'value2'} test_upgrade = None # Declare test Terraform.init return values @@ -107,11 +114,13 @@ def test_run_upgrade_none(self, mock_init, mock_check_result, mock_version): mock_check_result.return_value = expected_result # Execute the run function - result = action.run(test_plan_path, test_terraform_exec, test_backend, test_upgrade) + result = action.run(test_plan_path, test_terraform_exec, test_backend, test_upgrade, + test_env_variable_dict) # Verify the results self.assertEqual(result, expected_result) self.assertEqual(action.terraform.terraform_bin_path, test_terraform_exec) + self.assertEqual(action.set_env_variable_dict(test_env_variable_dict), True) mock_init.assert_called_with( backend_config=test_backend, capture_output=False, diff --git a/tests/test_action_plan.py b/tests/test_action_plan.py index 919628c..70de480 100644 --- a/tests/test_action_plan.py +++ b/tests/test_action_plan.py @@ -23,6 +23,7 @@ def test_run(self, mock_plan, mock_check_result, mock_version): test_terraform_exec = "/usr/bin/terraform" test_variable_dict = {'key1': 'value1', 'key2': 'value2'} test_variable_files = ["/terraform/test.tfvars"] + test_env_variable_dict = {'key1': 'value1', 'key2': 'value2'} # Declare test Terraform.plan return values test_return_code = 0 @@ -37,7 +38,8 @@ def test_run(self, mock_plan, mock_check_result, mock_version): # Execute the run function result = action.run(test_plan_path, test_state_file, test_target_resources, - test_terraform_exec, test_variable_dict, test_variable_files) + test_terraform_exec, test_variable_dict, test_variable_files, + test_env_variable_dict) # Verify the results self.assertEqual(result, expected_result) @@ -46,6 +48,7 @@ def test_run(self, mock_plan, mock_check_result, mock_version): self.assertEqual(action.terraform.terraform_bin_path, test_terraform_exec) self.assertEqual(action.terraform.var_file, test_variable_files) self.assertEqual(action.terraform.variables, test_variable_dict) + self.assertEqual(action.set_env_variable_dict(test_env_variable_dict), True) mock_plan.assert_called_with(capture_output=False, raise_on_error=False) mock_check_result.assert_called_with( test_return_code, @@ -67,6 +70,7 @@ def test_run_exit_code_2(self, mock_plan, mock_check_result, mock_version): test_terraform_exec = "/usr/bin/terraform" test_variable_dict = {'key1': 'value1', 'key2': 'value2'} test_variable_files = ["/terraform/test.tfvars"] + test_env_variable_dict = {'key1': 'value1', 'key2': 'value2'} # Declare test Terraform.plan return values test_return_code = 2 @@ -81,7 +85,8 @@ def test_run_exit_code_2(self, mock_plan, mock_check_result, mock_version): # Execute the run function result = action.run(test_plan_path, test_state_file, test_target_resources, - test_terraform_exec, test_variable_dict, test_variable_files) + test_terraform_exec, test_variable_dict, test_variable_files, + test_env_variable_dict) # Verify the results self.assertEqual(result, expected_result) @@ -90,6 +95,7 @@ def test_run_exit_code_2(self, mock_plan, mock_check_result, mock_version): self.assertEqual(action.terraform.terraform_bin_path, test_terraform_exec) self.assertEqual(action.terraform.var_file, test_variable_files) self.assertEqual(action.terraform.variables, test_variable_dict) + self.assertEqual(action.set_env_variable_dict(test_env_variable_dict), True) mock_plan.assert_called_with(capture_output=False, raise_on_error=False) mock_check_result.assert_called_with( test_return_code,