Skip to content
Alexander Holbreich
Go back

AWS automation

Recently I wrote about First steps with containers on AWS. Since then this project has grown a bit, but most of the resources were created manually. Early or later this needs to be automated.

Ansible

Since we had some experience with Ansible this was a first tool to try. I had first results relatively quickly. 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 were created to provision things 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 were too often not possible so in the end I felt not having enough control and decided to try other tools for AWS automation.

CloudFormation

So I turned to AWS native CloudFormation (CF). The documentation states, that it’s even possible to generate a CF description of the existing infrastructure… However while doing the first trials it turned out, that CF was not that reliable on the creation or on destroying of AWS resources. Something did not work 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 a huge JSON (or YAML) that lists all the AWS resources you have or need. It’s hard to maintain at the end even if you can break it into several files as well. On one meetup people reflected the 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 seems to be even more declarative than Ansible. The concept of state makes it much more reliable and understandable. Code can be structured as you like and modules are supported. Modules a written in the same simple and well readable way. There are only few concepts to understand:

  • providers
  • resources
  • data sources
  • variables
  • modules on top of all

Having that, you can read and understand on your own other people’s code from the first minute. Just by looking up documentation for parameter details. I also found it useful that it’s possible to “import” already existing AWS resources into the “managed 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, terraformfeels like the tool of the choice for now. However, even terraform is not perfect. For example, I’m still not satisfied with environment separation concepts. Currently, I have to maintain every environment in my own folder.

Own tool for AWS API

Except for CloudFormaton, all other tools are using AWS API and do not suffer from any issues. Also, I have already used API for small monitoring tools and found it pretty comfortable. So it might be an option to create your 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 a 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 your own, you probably will need to do a lot of compromises and comments in the code. And in the end, this infrastructure code tends to be 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 excited about your feedback.


Archived comments (7)

These comments were migrated from Disqus and are no longer accepting replies.

  • Martin Schuette

    Hello Alexander,
    to manage multiple environments with Terraform take a look at the new feature "state environments": https://www.terraform.io/do...

    This saves you from implementing the functionality in wrapper scripts. The general idea is to have only one "Terraform-Code", but run that code for multiple instances, each one defined by one variables and state file.

  • AlexH

    Hello Martin,

    very intriguing point. yes i saw it. "State environments" where introduced it in 0.9.x version... However this is only something that introduces kind of "branches" of local copy of the managed resources...
    or like documentation states:

    Environments are technically equivalent to renaming your state file. They aren't any more complex than that.

    .
    As i see it,
    1)the amount of moving parts between the enviroments must be reduced to a minimum. go out of the code completely,
    2) Diferences between Environments should be given to terraform code from outside somehow. E.g. as commandline vars?.
    Probably if you're lucky to have stages that are only differ in VPC_Id, and i can imagine that this is working well in this case ;)

    I may case, we're just at 30% of automation and need to reverse enginieer things often into code. So DEV and LIVE environments naturaly differs a lot. If we at 100% or 90% a will defenetily look at "state environment" feature as well. But however things may start looking different next weeks on our side and on terraform site as well.
    But for now terraform warns us:


    An environment alone should not be used to manage the difference between development, staging, and production.

    .

    P.S. Could you already gather some positive expiriences with "state environments"?

  • Martin Schuette

    I have not used the new "state environments" in a live setup. But with previous versions I have written several wrapper scripts for that same functionality, all among the lines of:


    terraform remote config s3://.../${env}
    terraform apply -var-file=${env}.tfvar

    But yes, differences between environments are difficult to model with Terraform. Having different instance sizes are easy; simple enable/disable settings are possible with count=1/0; but differences on a structural level are often impossible to model.

  • AlexH

    Ok looks like you sharped my vision of how it should work ideally ;) Our goal is to have very aligned DEV/LIVE environments, the "state environments" approach is truly contributes to it. Since that it makes sense to keep this vision in mind...

    Oh. And is was not aware of:

    terraform apply -var-file=${env}.tfvar

    thx!

    P.S. What is your approach regarding secrets? (Passwords etc.) Are they just externalized in -var-file and maybe not checked in with resource definitions or is there anything much better?

  • Martin Schuette

    I still have not found a good answer to secret management. :-(

    One previous project stored nearly everything in Jenkins and wrote secrets into AMIs; that seemed like not the worst compromise between usability and security.

    My only suggestion would be to have one setup stage deal with them, either Terraform, or Packer, or maybe Puppet/Chef/Ansible, and then build security around that. Having multiple sources of secrets only causes more headaches.

  • AlexH

    Ok. See same problem with secrets.
    P.S. Switched to state environments and custon scripts.. Works fine so far!! ;)

  • Steve Mushero

    We feel you MUST be able to reverse engineer existing systems into your models, AND allow for manual changes that actually happen for many reasons (bugs, automation failure, mistakes, emergency fixes).

    So our new OpsStack product (www.OpsStack.io) will support full Reverse, Forward, and Change Engineering - we can import/export CF and will probably do round-trip Terraform and its State file for the fun of it, too.

    We also support Full-Stack, so not only the cloud, but also OS, Services (MySQL, Nginx, etc.) for forward and reverse engineering - so Full-Stack, Full-Life Cycle with monitoring, management, tuning, expert-system troubleshooting, Audit & Compliance, logging, etc.