I’ve spent the better part of the week pulling apart one of my own Cloudformation stacks trying to make it suitable to take with us between clients, and as such I’ve picked up some ideas on how to make it more portable between environments. I’ll probably read some more blogs on this stuff in the coming weeks, but here’s the small collection of tips I’ve come away with trying to get this stack into our new account.
Name things in obvious ways
Always use environment names (and client names, if applicable)
One easy way to make sure people have fewer excuses to delete
things on me is to make sure EVERY resource has the client
name and environment in their identifier, for example
initrode-staging-bastion
.
If people are looking at the console and manage to delete anything
with production
in its name with termination protection on, I can
make a good guess that it was either deliberate or I have some
serious education to spread around.
We split our environments into different accounts, but I still believe this is important to do. It’s one more check to make sure no one destroys anything important.
Always put the purpose in the name
Our system is going to need to handle multiple configurations. To deploy a new environment, it’s going to be incredibly difficult for us to know what to deploy (until my super secret environment deployment tool is ready) if we don’t have well named resources.
This is a pretty simple one to follow,
initrode-production-contact-database
or the like would suffice.
Prepend Lambdas With Their Source Events
This follows along with the suggestion above. Better visibility at a glance.
initrode-production-kinesis-event-insert
General Template Cleanliness
Use Parameters
Something I realised I did was peppering the client name all
through my template instead of using !Ref ClientName
to use
the parameter value.
Mappings… Maybe
This is going to be a problem for me long term and I think I’m going to need a custom resource to control all this, but for handfuls of environments mappings are nice enough way to configure things like subnets and security groups which can be a pain to do as parameters in your deployment tool.
I like to lay mine out like this
Mappings:
Foobar:
initrode:
production: foo
staging: bar
initech:
production: baz
training: fizz
which makes it easy to reference with
Fn::FindInMap: [Foobar, !Ref ClientName, !Ref EnvironmentName]
Predictable Naming and Standard Variables
I have a defacto standard in my template of ClientName
and
EnvironmentName
, meaning I know it’s going to be there
when I need it.
Conclusion
I think this is mostly common sense if you’ve been a developer for a little while, but it can be a good thing to put your thoughts down to kind of quantify it.