When decomposing a monolith application into microservices, authentication is always a challenge. Packaging all the security access control logic into a common base library would cause heavy coupling between microservices and maximize exposure of your security database. Instead, we can implement a token service to handle stateful authentication in our service.
A token service is a web service whose sole responsibility is creating bearer tokens (JWTs) and providing the means (a JWKS) to verify the tokens. The token service is the only service with permissions to read and write the authorization database. …
I generally write PowerShell with a pathological aversion to state and side-effects. In reality, these undesirable patterns are often unavoidable, especially in DevOps. Unavoidable CLIs like
git and compilers require the stateful shell cursor to move to a different directory before the CLI can be invoked; mutable collections must be maintained; integration tests and infrastructure code often requires provisioning of temporary resources in the cloud — all of these operations change the state of our system and subsequently put the system in an unknown, difficult-to-manage state.
In this article, we review a few examples of leveraging higher-order functions to abstract away side-effect management from our scripts. …
Part 6 of Declarative DevOps Microframeworks
Configuration Management is hard. It’s hard because if you create one config per environment, the number of configs you manage can grow exponentially with a high rate of overlap, making config changes tedious, and prone to human error and configuration drift. It’s hard because engineers casually choose heavy platforms (Chef, Puppet, Ansible, etc.) to solve the problem without sufficient experience to understand those platform’s patterns, while also falling into vendor lock. Most importantly, it’s hard because people implement configuration management scripts without properly formalizing the problem and implementing an appropriate solution.
We will seek inspiration from popular Declarative DevOps frameworks like Helm and ARM/CloudFormation to implement our own declarative microframework in PowerShell for managing configurations across non-homogenous environments. Using this approach my team was able to reduce lines of config code by 91%. The completed solution is only a couple hundred lines (including tests, robust interfaces, and additional utilities). …
Part 8 of Declarative DevOps Microframeworks
If you’ve started a new code base, you probably left a lot of
TODOs in your code comments to indicate that you need to circle back on the implementation of a specific area at a later date. These
TODOs help you focus on the overall code flow rather than getting distracted by a small implementation detail.
How do you keep track of these
TODOs? We can leverage PowerShell’s native RegEx and I/O capabilities to create a light-weight script for finding and aggregating
TODOs in our repo.
Because we are writing a simple aggregation script without any need for state, we will write our script adhering to a functional paradigm. With this approach, we define our data first. We start with what we have (our inputs) and what we want (our outputs). …
Part 7 of Declarative DevOps Microframeworks
A script is idempotent when it can be run multiple times without different outcomes or errors. In DevOps, we frequently describe complex systems then set them to their desired state. The components of the system may be in various states, so it is important that our scripts are idempotent and do not assume the system’s initial configuration.
To obtain idempotency, developers typically apply one of a few patterns —
elseblocks that check if the resource is in the desired state before setting it. …
Part 3 of Declarative DevOps Microframeworks
DevOps and Microframeworks are two words that I have yet to find paired together on the internet. DevOps teams, however, find themselves needing to implement custom code more often than most domains. DevOps Microframeworks help manage the inevitability and complexity of writing custom DevOps code.
Conway’s Law states,
organizations which design systems … are constrained to produce designs which are copies of the communication structures of these organizations.
— M. Conway
For our purposes, Conway’s Law states that there can never be a one-size-fits-all solution for software because every company has different team structures and processes. There will always be a need to write custom code to solve a problem because no two teams will ever be solving the same problem in the same context. …
Part 2 of Declarative DevOps Microframeworks
Declarative Programming is not a new concept — but its use describing DevOps tools has recently exploded. It may seem like just another trendy buzzword, but Declarative Programming has some unique benefits for DevOps that ensure it is here to stay.
Declarative Programming is often conflated with Functional Programming, but is somewhat different. The easiest way to understand the Declarative paradigm is to contrast it to “normal” Imperative code.
If you are asking this question, a good example of imperative code is your current codebase. Imperative code defines logic as a sequence of steps. Each step waits for the previous step to complete before continuing, and each step modifies the state of your system. …
Part 4 of Declarative DevOps Microframeworks
PowerShell modules (if designed correctly) are completely modular and portable — the ideal solution for packaging DevOps microframeworks. While you could try to use a private PowerShell Gallery instance or Azure Artifacts to host your module, by far the simplest and easiest way to develop and release your module for private consumption is to store them in
git and copy the files at deployment time.
This guide will show you how to build a PowerShell module, reference it in your other projects, and deploy it privately.
PS /projects> mkdir MyModule
PS /projects> cd MyModule
Part 5 of Declarative DevOps Microframeworks
PowerShell, more so than most languages, can be extremely difficult to manage in large code bases. While REST APIs and apps have standard design patterns you can follow, the same does not necessarily apply to DevOps codebases. As a result, many codebases lack strong separation between user-facing interfaces and internal logic, and subsequently grow hard to read and hard to maintain. We can leverage some common patterns from other languages to work with (not against) PowerShell to keep large PowerShell codebases maintainable.
MVC is a very common software engineering pattern for large user-facing applications, whether they are ASP.NET websites or iOS applications. MVC cleanly separates presentational logic from business logic by dividing application code into Models, Views, and Controllers. Just like graphical user interfaces, command-line interfaces can benefit from this same separation. …
Declarative DevOps Microframeworks is the most robust, portable, and scalable pattern for managing your DevOps systems. This series will help you understand the concepts behind Declarative DevOps Microframeworks, then walk you through implementing some common use cases in the most DevOps-friendly language: PowerShell.
First, learn about Declarative DevOps systems, the Microframeworks pattern, and how to package a DevOps microframework.