terraform: do not immediately fail if a lock is held
terraform will wait 15 minutes to see if the state is released before returning an error fixes: #16
This commit is contained in:
parent
a2abaabd12
commit
a7432a6b96
1 changed files with 36 additions and 11 deletions
|
@ -26,26 +26,40 @@ class TerraformAutomation(BaseAutomation):
|
||||||
self.tf_posthook(prehook_result=prehook_result)
|
self.tf_posthook(prehook_result=prehook_result)
|
||||||
return True if returncode == 0 else False, logs
|
return True if returncode == 0 else False, logs
|
||||||
|
|
||||||
def tf_apply(self, refresh: bool = True, parallelism: Optional[int] = None) -> Tuple[int, List[Dict[str, Any]]]:
|
def tf_apply(self, *,
|
||||||
|
refresh: bool = True,
|
||||||
|
parallelism: Optional[int] = None,
|
||||||
|
lock_timeout: int = 15) -> Tuple[int, List[Dict[str, Any]]]:
|
||||||
if not parallelism:
|
if not parallelism:
|
||||||
parallelism = self.parallelism
|
parallelism = self.parallelism
|
||||||
tf = subprocess.run(
|
tf = subprocess.run(
|
||||||
['terraform', 'apply', f'-refresh={str(refresh).lower()}', '-auto-approve',
|
['terraform',
|
||||||
f'-parallelism={str(parallelism)}', '-json'],
|
'apply',
|
||||||
|
'-auto-approve',
|
||||||
|
'-json',
|
||||||
|
f'-refresh={str(refresh).lower()}',
|
||||||
|
f'-parallelism={str(parallelism)}',
|
||||||
|
f'-lock-timeout={str(lock_timeout)}m',
|
||||||
|
],
|
||||||
cwd=self.working_directory(),
|
cwd=self.working_directory(),
|
||||||
stdout=subprocess.PIPE)
|
stdout=subprocess.PIPE)
|
||||||
logs = []
|
logs = []
|
||||||
for line in tf.stdout.decode('utf-8').split('\n'):
|
for line in tf.stdout.decode('utf-8').split('\n'):
|
||||||
if line.strip():
|
if line.strip():
|
||||||
logs.append(json.loads(line))
|
logs.append(json.loads(line))
|
||||||
return tf.returncode, logs
|
return tf.returncode, str(logs)
|
||||||
|
|
||||||
def tf_generate(self):
|
def tf_generate(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def tf_init(self):
|
def tf_init(self, *,
|
||||||
|
lock_timeout: int = 15):
|
||||||
|
# The init command does not support JSON output
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
['terraform', 'init'],
|
['terraform',
|
||||||
|
'init',
|
||||||
|
f'-lock-timeout={str(lock_timeout)}m',
|
||||||
|
],
|
||||||
cwd=self.working_directory())
|
cwd=self.working_directory())
|
||||||
|
|
||||||
def tf_output(self) -> Dict[str, Any]:
|
def tf_output(self) -> Dict[str, Any]:
|
||||||
|
@ -55,13 +69,24 @@ class TerraformAutomation(BaseAutomation):
|
||||||
stdout=subprocess.PIPE)
|
stdout=subprocess.PIPE)
|
||||||
return json.loads(tf.stdout)
|
return json.loads(tf.stdout)
|
||||||
|
|
||||||
def tf_plan(self):
|
def tf_plan(self, *,
|
||||||
|
refresh: bool = True,
|
||||||
|
parallelism: Optional[int] = None,
|
||||||
|
lock_timeout: int = 15):
|
||||||
tf = subprocess.run(
|
tf = subprocess.run(
|
||||||
['terraform', 'plan'],
|
['terraform',
|
||||||
|
'plan',
|
||||||
|
'-json',
|
||||||
|
f'-refresh={str(refresh).lower()}',
|
||||||
|
f'-parallelism={str(parallelism)}',
|
||||||
|
f'-lock-timeout={str(lock_timeout)}m',
|
||||||
|
],
|
||||||
cwd=self.working_directory())
|
cwd=self.working_directory())
|
||||||
# TODO: looks like terraform has a -json output mode here but it's
|
logs = []
|
||||||
# more like JSON-ND, task is to figure out how to yield those records
|
for line in tf.stdout.decode('utf-8').split('\n'):
|
||||||
# as plan runs, the same is probably also true for apply
|
if line.strip():
|
||||||
|
logs.append(json.loads(line))
|
||||||
|
return tf.returncode, str(logs)
|
||||||
|
|
||||||
def tf_posthook(self, *, prehook_result: Any = None) -> None:
|
def tf_posthook(self, *, prehook_result: Any = None) -> None:
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue