I have lived the first 1/2 of the article for the last 1.5+ years and have gone through that mental cycle. We've been moving our product from AWS to GCP. We have a custom deployment tool based of off Capistrano, Chef and Cloud Formation to setup our stack in AWS. There are a couple things that have helped me and may help others who have to do a similar thing (or any setup for that matter).<p>Tooling: I looked at them all. yaml, kustomize, helm, deployment manager, etc and in the end I went with Terraform. The reasoning was simple. We deploy Infrastructure, not kubernetes services and terraform lets you do the entire thing with one tool. It has the ability to do loops and clunky if-like statements but if you want real programming power then you can create your own terraform provider which is what we did. The pattern of how to create a provider already exists so you are not re-inventing the wheel. We even add our own services to our provider so that we have one tool for setup of GCP resources -> Kubernetes resources -> our own service(s) resources. 1 tool, 1 flow, 1 statefile and the same pattern when working with it all.<p>Establish patterns: "My service is a multi-tenant service and should do X". Don't allow people to get away with special cases when it comes to deploying infrastructure. Create patterns and stick to them. As an example, one pattern I have is that I have 4 variables that all of my terraform modules use: project, region, cluster and tenant. A combination of any of those variables is enough to create unique resources for everything you deploy... dns names, storage buckets, databases, service accounts, namespaces, clusters, etc. Those variables allow me to know where your git repos are, what GCP project your deployment lives in, what kubernetes cluster you are on and what namespace you are in. Patterns.<p>Keep it simple: There will be pressure to have custom settings and provide as much flexibility as possible. Try and avoid this. Set defaults for values and try and reduce the number of configuration options available to others. In our case, there were around hundreds of environment variables being set on a deploy and most of them were the same. I took the list, standardized the environment variable names, DATABASE_USER, MYSQL_USER, MYSQL_USERNAME, DB_USERNAME... come on guys!, and deployed them as a secret in kubernetes so that all of our running services can access them. Reduce complexity.