How to Reduce Terraform Logs with Finite State Machine in Python

The aim of this page📝 is to illustrate the chapter about finite state machines from Pragmatic Programmer with my little implementation.

Pavol Kutaj
3 min readApr 18, 2023

First, let’s look at the real-life finite-state machine

  • This is a Terraform log file reducer
  • Every day, certain alerts are fired that warn about the existing “drift”, i.e. planned infrastructure config changes — they need to be looked at and decided if we’re good to apply, or we need to contact a client (as this is a managed account), the number of scenarios is huge, the full-automation therefore cumbersome
  • Therefore, I gather all logs and, them into a single input file and want to see only the relevant bits (which is ~10% of the whole content logs that are wordy)

Start with Why: Of course, state machines are useful because of the requirement of statefulness

  • In other words, as long as your functions are pure — that is, a certain input always, in every circumstance, has the same output — you don’t need one a state machine
  • In the classical SICP textbook, then, the question of state comes pretty late — around halfway through the entire course
  • Often, though, context — and therefore timematters, e.g.: …I have quotation marks in the input of "foobar" ...and at one point the quotation marks mark the beginning of a word ...and at another point, the quotation marks the end of a word ⟹ then, the state machine is something you could utilize! ...Because based on what state the system is in (context!), you're going to handle the quotes (input) differently. ...Either you're going to start interpreting the upcoming word, or you're going to end it and wait for, say, a space

For the definition, I’m not using a textbook one, but the PragProg one

  • As per pragmatic programmers, FSM is an event-handling specification
  • The essential components consist of
  • This leads to the following 5-steps
  • From the above it seems clear that event_handling with event listeners and higher-order-functions, are all part of state machine, too

For this particular one we have the following state table — which is part of the domain/problem analysis

Sometimes, an event may be identical to input, often input is a trigger for an event

  • for the latter scenario, I’ve created another table (this time it goes directly into a dict)
  • we need a handler that takes a line from a file and maps it to the event
  • there is an n:1 relationship between triggers and events
  • importantly, the handler needs to return default event in case none of the defined ones are triggered

As for case analysis on the action, Python before 3.10 does not have the switch statement (by design)

  • in other words, there is a part of code containing many elifs
  • as a sidestep, Python docs are explicit about the original absence of switch (let's not talk about switch, it's a long debate)

There can be zero or more elif parts, and the else part is optional. The keyword ‘elif’ is short for ‘else if’, and is useful to avoid excessive indentation. An if … elif … elif … sequence is a substitute for the switch or case statements found in other languages.

4. More Control Flow Tools — Python 3.11.2 documentation

Finally, in case of malformed input, I raise an exception

  • Since my input is a set of terraform logfiles with certain beginning and end, I crash as soon as it’s clear that the syntax is broken …e.g. I may get only half of the file, etc.

--

--

Pavol Kutaj

Today I Learnt | Infrastructure Support Engineer at snowplow.io with a passion for cloud infrastructure/terraform/python/docs. More at https://pavol.kutaj.com