AWS automation

Recently i wrote about First steps with containers on AWS. Since then this project has grown a bit, but most of the resource where created manually. Early or later this need to be automated.

Ansible

Since we had some experience with Ansible this was a first tool to try. I had first results relative quick. However Ansible felt not the right tool for the job. The fact that you work with localhost destroys a lot of Ansibles charm that i saw while provisioning Virtual machines. Also Chef, Puppet also where created to provision thing on hosts (not creating them) and are often classified as configuration management tools.

- hosts: localhost
  connection: local
  gather_facts: False
...

As well the quality of the AWS modules was not that good, so that idempotent operations where to often not possible so at the end i felt not having enough controll and decided to try other tools for AWS automation.

CloudFormation

So i turned to AWS native CloudFormation (CF). The documentation statet, that it's even possibel to generate CF description of the existing infrastructure... However while doing first trials it turned out, that CF was not that reliable on the creation or on destroying of AWS resources. Something did not worked to 100% with CF even when i played with kube-aws, that generates CF under the hood and even with that CF AWS could not delete resources and could not provide proper feedback on the error.

Furthermore CF is just huge json (or yaml) which list all the AWS resources you have or need. It's hard to maintain at the end even if you can break it in several files as well.
On one meetup people reflected same experiences to me, so CF slipped down my priority list.

Terraform

Hashicorp's terraform finds good responses on the internet, so i tried it, and liked it for simplicity. The code seem to be even more declarative that Ansible's. The concept of state makes it much more reliable and understandable. Code can be structured as you like and modules are supported. Modules a writen in the same simple an whel readabel way. There are anly few concept to understand: proviers, resources, data sources, variables and modules on top, so you can read and understand own ond other people's code from the first minute lloking up documentation sometimes. I also found it useful that it's possible to "import" already existing AWS resources into the "manged state" even no resource definition is created it's still helping.

//Example of VPC and IGW resource definitions
resource "aws_vpc" "mod" {  
  cidr_block           = "${var.cidr}"
  enable_dns_hostnames = "${var.enable_dns_hostnames}"
  enable_dns_support   = "${var.enable_dns_support}"
  tags                 = "${merge(var.tags, map("Name", format("%s", var.name)))}"
}

resource "aws_internet_gateway" "mod" {  
  vpc_id = "${aws_vpc.mod.id}"
  tags   = "${merge(var.tags, map("Name", format("%s-igw", var.name)))}"
}

So, *terraform *feels like the tool of the choice for now. How ever even terraform is not perfect. For example i'm still not satisfied with environment separation concepts. Currently i have to maintain ever environment in own folder.

Own tool for AWS API

Except of CloudFormaton, all other tools are using AWS API and do not suffer from any issues. Also i have already used api for small monitoring tool and found it pretty comfortable. So it might be an option to create own tool(s) that use AWS API in the programming language you comfortable with or that is more appropriate for your needs E.g. java or maybe better Go in case of a console tool.

Summarizing all that i think i can create priority of the tools i would like to use for AWS automation:

  • Terraform
  • Ansible
  • Own API console tool (Golang)
  • CloudFormation

P.S. Existing infrastructure

An extra topic that adds much complexity to the topic is the existence of manually created resources. For example i would like to include a lot of manually created AWS resources, that are used in production. Reasoning on this i see a fundamental problem, that manually created resources are tending to break patterns. And because of that, there is no matching community module for this and if you write you own, you probably will need to do a lot of compromises and comments in the code. And at the end this infrastructure code tend to by ugly and strange.

By that maybe there is no sense at all in this kind of reverse engineering work of existing aws infrastructure to code. At least not to all parts and it's better to recreate the infrastructure from new code as far as possible and invest more time and care on smooth migration.

As always exited about your feedback.