How should I model my distributions?

There are no technical limit to what a Attini distribution can do, how its built or what it can be used for. But through experience we found some best practices that will help you model your environment in an efficient way.

The golden rule is to make sure that one distribution is managed by one team. Sharing management of one distribution will lead to security vulnerabilities when one team can inject code into another teams domain. There is also the risk of conflicts if several teams deploy the same distribution at the same time to the same environment.

Another way to look at it is One git repo equals one distribution, this will keep every thing simple and transparent. However it does not allow for much reusability or flexibility so we often end up with some “merging” logic. This means that you fetch files from external sources (or other Attini distributions) and bundle the files with you distribution. These files are often reusable CloudFormation templates, generic build scripts or config files are managed by other teams. If you do the “merging” in the build step, the distribution becomes immutable, if you do it during deployment it becomes easier to update but more unpredictable.

An other important perspective is size and deployment frequency. You deploy changes to you infrastructure at different frequencies, you often introduce changes more frequently higher up in you application stack. Meaning that you update your application more often then you database, and you update your database more often then your network. The bigger the Attini distribution is, the longer it will take to deploy and the harder it will be to get a proper overview of your deployment scope. So if you have a bigger environment, splitting you distributions into layers (networks, databases, applications) might make sense.

Infrastructure or Application distributions

These are the most “straight forward” distributions and they simply set up our environment. For example you can have a simple distribution called something like [company name]-infrastructure and it would deploy the networks, databases, CDNs, auto-scaling groups or kubernetes clusters for your environment.

A lager organization might want to break this up into smaller domains like, network, databases, 3rd part software, data warehouse, the monolith etc.

Shared artifacts

You often have files that you want to share with other domains, an example would be standard templates, configuration for your central network integrations ect.

You can make a distribution without a deployment plan for these artifacts simply so that they can be consumed by other distributions. When a Attini distribution is deployed, it will always save the distributions latest “distribution id” in AWS SSM Parameter store under the path: /attini/distributions/{distribution-name}. So if you have a distribution called shared-artifacts its content will always be stored in a versioned way in the attini-artifact-store-{region}-{account-id} bucket under the path [environment]/shared-artifacts/{distribution-id}/distribution-origin/

This way any other distribution can fetch the latest shared-artifacts id from AWS SSM Parameter store using that id, it can find the latest files on s3 and download them during build or deployment.

If your “shared-artifacts” need some type of build, example synthesize an aws cdk project, or package an AWS SAM app you can and a small deploy plan that runs your build an puts the output in s3 attini-artifact-store-[region]-[account-id]/{environment}/shared-artifacts/{distribution-id}/{my-own-files}. That way you can extend you toolbox after you own needs.

Platform distribution

We often need small “one of” automation for our IT platforms, it can be everything from a smart archiving solution, backup restore tests, CloudFormation macros etc. Our experience is that these typ of “Platform” services tend to escalate and they are often hard to fit into your normal deploy flows. These types of Platform automation is often needed cross different types of environments*.

The Platform distribution is often small cloud native applications or other serverless light weight automation that are hard maintain, not because they are are complex, but because they are MANY small functions deployed to MANY different environments that often lack a standard CI/CD flow.

Packaging all these small applications into one or a few “Platform distributions” reduces a lot of maintenance efforts and it helps to standardize your cloud environments.

Your other distributions often have a dependency on your Platform distributions, if you for example deploy you AWS SSM Patch baseline in your Platform distribution, you infrastructure distribution will be dependent on it to function properly. This is ok, but be careful to build a circular dependency between the distributions. A common circular dependency is with the network, many platforms services have to act within the network, for example if it needs to connect to a private database. But the network is created by infrastructure-distribution that is dependent on your platform-distribution. This is easily fixed by breaking up the platform distribution into two different types, one completely serverless and independent and one infrastructure-platform-distribution that can be deployed after the infrastructure-distribution (that contains the vpc).

* Company’s often have different types of environments, the normal one that gets all attention is the “application environment” where you run you software. But you often have other environment ex: one central environment for you dev tools (build server, artifact store etc), one that isolate and maintain your backups, one the you run 3rd party software in, one for you back office applications like Active directory and exchange server etc.