A couple of months ago I joined the Infra team at Coinbase. One of the first projects I worked on was codifying all of our cloud infrastructure. We evaluated a number of different options for how to codify that infrastructure, and ended up using a thin wrapper called GeoEngineer (Geo for short) over Terraform. My colleagues Graham Jenson and Rob Witoff have written and spoken about GeoEngineer previously, and I think they’ve done a good job explaining why we built it and the purpose it serves. Today I’m going to talk about templating with Geo, why templates are useful and how they compare to Terraform modules.
At a high level, Geo is organized around environments. These correspond to the particular AWS account or VPC that you are planning and/or applying your resources into. Additionally, you can further organize your code via projects, which is a logical grouping of resources within an environment. These concepts help you think about where to define your resources and how to group them, but as you add more and more resources, you need additional logic to help keep things simple and maintainable. This is where templates come into play — they let you codify best practices.
For example, as we were migrating towards what we’re calling consolidated login and codifying all of the resources roles, a common pattern was defining a role for some project, letting some Amazon service assume that role, and giving that role some permissions.
Sample role for a lambda function
In most of these cases, the
assume_role_policy for each service was the same, just with a different service name, i.e.
lambda.amazonaws.com . Additionally, the
policy-name , and
attachment-name were similarly the same, or derived from the same base. And the only purpose of the
aws_iam_policy_attachment is to connect the two resources we just created, it doesn’t require any additional information. So in order to create those 3 resources, all we really need to know is the role name, the service for the assume role policy, and a list of policy files. It’s a complex implementation with a simple interface.
This allowed us to create a
RoleWithPolicies template, which really simplified things.
Using this new template, we can codify the role from earlier as follows:
Sample role codified with Geo, demonstrating attaching multiple policies
The great thing about this particular template is that the more policies you need to attach to a single role, the more lines of code you save. We’ve easily saved hundreds of lines using templates for users, roles, and groups. Another benefit is that the naming ends up being more consistent, which just satisfies my inner OCD.