terraform: patch state 'planned' outputs and perform minor refactor (#52004)
* patch state 'planned' outputs and perform minor refactor * reconcile with pep8 and pylint * remove a space... * update changed to only flip when >0 added, changed, or destroyed is detected * add state dependecy to conditional change check * fix typo * reconcile with pep8[E317] * add a changelog fragment
This commit is contained in:
parent
48187d5659
commit
6f585b6ee9
2 changed files with 26 additions and 29 deletions
|
@ -0,0 +1,2 @@
|
||||||
|
bugfixes:
|
||||||
|
- terraform - fixed issue where state "planned" wouldn't return an output and the project_path had to exist in two places (https://github.com/ansible/ansible/issues/39689)
|
|
@ -241,28 +241,28 @@ def remove_workspace(bin_path, project_path, workspace):
|
||||||
_workspace_cmd(bin_path, project_path, 'delete', workspace)
|
_workspace_cmd(bin_path, project_path, 'delete', workspace)
|
||||||
|
|
||||||
|
|
||||||
def build_plan(bin_path, project_path, variables_args, state_file, targets, plan_path=None):
|
def build_plan(command, project_path, variables_args, state_file, targets, state, plan_path=None):
|
||||||
if plan_path is None:
|
if plan_path is None:
|
||||||
f, plan_path = tempfile.mkstemp(suffix='.tfplan')
|
f, plan_path = tempfile.mkstemp(suffix='.tfplan')
|
||||||
|
|
||||||
command = [bin_path, 'plan', '-input=false', '-no-color', '-detailed-exitcode', '-out', plan_path]
|
plan_command = [command[0], 'plan', '-input=false', '-no-color', '-detailed-exitcode', '-out', plan_path]
|
||||||
|
|
||||||
for t in (targets or []):
|
for t in (module.params.get('targets') or []):
|
||||||
command.extend(['-target', t])
|
plan_command.extend(['-target', t])
|
||||||
|
|
||||||
command.extend(_state_args(state_file))
|
plan_command.extend(_state_args(state_file))
|
||||||
|
|
||||||
rc, out, err = module.run_command(command + variables_args, cwd=project_path, use_unsafe_shell=True)
|
rc, out, err = module.run_command(plan_command + variables_args, cwd=project_path, use_unsafe_shell=True)
|
||||||
|
|
||||||
if rc == 0:
|
if rc == 0:
|
||||||
# no changes
|
# no changes
|
||||||
return plan_path, False
|
return plan_path, False, out, err, plan_command if state == 'planned' else command
|
||||||
elif rc == 1:
|
elif rc == 1:
|
||||||
# failure to plan
|
# failure to plan
|
||||||
module.fail_json(msg='Terraform plan could not be created\r\nSTDOUT: {0}\r\n\r\nSTDERR: {1}'.format(out, err))
|
module.fail_json(msg='Terraform plan could not be created\r\nSTDOUT: {0}\r\n\r\nSTDERR: {1}'.format(out, err))
|
||||||
elif rc == 2:
|
elif rc == 2:
|
||||||
# changes, but successful
|
# changes, but successful
|
||||||
return plan_path, True
|
return plan_path, True, out, err, plan_command if state == 'planned' else command
|
||||||
|
|
||||||
module.fail_json(msg='Terraform plan failed with unexpected exit code {0}. \r\nSTDOUT: {1}\r\n\r\nSTDERR: {2}'.format(rc, out, err))
|
module.fail_json(msg='Terraform plan failed with unexpected exit code {0}. \r\nSTDOUT: {1}\r\n\r\nSTDERR: {2}'.format(rc, out, err))
|
||||||
|
|
||||||
|
@ -317,6 +317,11 @@ def main():
|
||||||
else:
|
else:
|
||||||
select_workspace(command[0], project_path, workspace)
|
select_workspace(command[0], project_path, workspace)
|
||||||
|
|
||||||
|
if state == 'present':
|
||||||
|
command.extend(APPLY_ARGS)
|
||||||
|
elif state == 'absent':
|
||||||
|
command.extend(DESTROY_ARGS)
|
||||||
|
|
||||||
variables_args = []
|
variables_args = []
|
||||||
for k, v in variables.items():
|
for k, v in variables.items():
|
||||||
variables_args.extend([
|
variables_args.extend([
|
||||||
|
@ -328,11 +333,6 @@ def main():
|
||||||
|
|
||||||
preflight_validation(command[0], project_path, variables_args)
|
preflight_validation(command[0], project_path, variables_args)
|
||||||
|
|
||||||
if state == 'present':
|
|
||||||
command.extend(APPLY_ARGS)
|
|
||||||
elif state == 'absent':
|
|
||||||
command.extend(DESTROY_ARGS)
|
|
||||||
|
|
||||||
if module.params.get('lock') is not None:
|
if module.params.get('lock') is not None:
|
||||||
if module.params.get('lock'):
|
if module.params.get('lock'):
|
||||||
command.append('-lock=true')
|
command.append('-lock=true')
|
||||||
|
@ -345,35 +345,30 @@ def main():
|
||||||
command.extend(['-target', t])
|
command.extend(['-target', t])
|
||||||
|
|
||||||
# we aren't sure if this plan will result in changes, so assume yes
|
# we aren't sure if this plan will result in changes, so assume yes
|
||||||
needs_application, changed = True, True
|
needs_application, changed = True, False
|
||||||
|
|
||||||
if state == 'planned':
|
|
||||||
plan_file, needs_application = build_plan(command[0], project_path, variables_args, state_file, module.params.get('targets'), plan_file)
|
|
||||||
if state == 'absent':
|
if state == 'absent':
|
||||||
# deleting cannot use a statefile
|
|
||||||
needs_application = True
|
|
||||||
# add variables settings to destroy command
|
|
||||||
command.extend(variables_args)
|
command.extend(variables_args)
|
||||||
elif plan_file and os.path.exists(plan_file):
|
elif state == 'present' and plan_file:
|
||||||
command.append(plan_file)
|
if os.path.exists(project_path + "/" + plan_file):
|
||||||
elif plan_file and not os.path.exists(plan_file):
|
command.append(plan_file)
|
||||||
module.fail_json(msg='Could not find plan_file "{0}", check the path and try again.'.format(plan_file))
|
else:
|
||||||
|
module.fail_json(msg='Could not find plan_file "{0}", check the path and try again.'.format(plan_file))
|
||||||
else:
|
else:
|
||||||
plan_file, needs_application = build_plan(command[0], project_path, variables_args, state_file, module.params.get('targets'), plan_file)
|
plan_file, needs_application, out, err, command = build_plan(command, project_path, variables_args, state_file,
|
||||||
|
module.params.get('targets'), state, plan_file)
|
||||||
command.append(plan_file)
|
command.append(plan_file)
|
||||||
|
|
||||||
if needs_application and not module.check_mode and not state == 'planned':
|
if needs_application and not module.check_mode and not state == 'planned':
|
||||||
rc, out, err = module.run_command(command, cwd=project_path)
|
rc, out, err = module.run_command(command, cwd=project_path)
|
||||||
if state == 'absent' and 'Resources: 0' in out:
|
# checks out to decide if changes were made during execution
|
||||||
changed = False
|
if '0 added, 0 changed' not in out and not state == "absent" or '0 destroyed' not in out:
|
||||||
|
changed = True
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
module.fail_json(
|
module.fail_json(
|
||||||
msg="Failure when executing Terraform command. Exited {0}.\nstdout: {1}\nstderr: {2}".format(rc, out, err),
|
msg="Failure when executing Terraform command. Exited {0}.\nstdout: {1}\nstderr: {2}".format(rc, out, err),
|
||||||
command=' '.join(command)
|
command=' '.join(command)
|
||||||
)
|
)
|
||||||
else:
|
|
||||||
changed = False
|
|
||||||
out, err = '', ''
|
|
||||||
|
|
||||||
outputs_command = [command[0], 'output', '-no-color', '-json'] + _state_args(state_file)
|
outputs_command = [command[0], 'output', '-no-color', '-json'] + _state_args(state_file)
|
||||||
rc, outputs_text, outputs_err = module.run_command(outputs_command, cwd=project_path)
|
rc, outputs_text, outputs_err = module.run_command(outputs_command, cwd=project_path)
|
||||||
|
|
Loading…
Reference in a new issue