Version your entire infrastructure with terraform

A few days ago, Codeship published a blog post about how they version their DNS configuration using a small tool they built, which uses DNSimple’s API.
I love DNSimple, but for various reasons, I’m using Route53 for my DNS.

I also love the idea of managing DNS configuration in GIT, but I’d like to manage my entire infrastructure’s configuration in GIT.
Yes, at the moment I don’t have any hosted server, but I could want to start EC2 instances for, say … things. This is the reason why I have decided not to use a custom built tool to manage my DNS configuration, but Terraform.
Terraform is a Go tool built by Hashicorp (the company behind Vagrant) and which allows to manage your entire infrastructure’s configuration with config files.

It is to me, one of the best, yet unknown modern tools to use when managing servers. I’m letting you follow their awesome getting started article. But as a short example, here’s what my private DNS configuration looks like for the domain dmathieu.com:

variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "region" {
    default = "eu-west-1"
}

provider "aws" {
    access_key = "${var.aws_access_key}"
    secret_key = "${var.aws_secret_key}"
    region = "${var.region}"
}

resource "aws_route53_zone" "dmathieu" {
    name = "dmathieu.com"
}

resource "aws_route53_record" "root" {
    zone_id = "${aws_route53_zone.dmathieu.zone_id}"
    name = "dmathieu.com"
    type = "A"
    ttl = "300"
    records = ["192.30.252.153", "192.30.252.154"]
}

resource "aws_route53_record" "root_mx" {
    zone_id = "${aws_route53_zone.dmathieu.zone_id}"
    name = "dmathieu.com"
    type = "MX"
    ttl = "300"
    records = ["1 ASPMX.L.GOOGLE.COM.", "5 ALT1.ASPMX.L.GOOGLE.COM.",
      "5 ALT2.ASPMX.L.GOOGLE.COM.", "10 ASPMX2.GOOGLEMAIL.COM.", "10 ASPMX3.GOOGLEMAIL.COM."]
}

resource "aws_route53_record" "www" {
    zone_id = "${aws_route53_zone.dmathieu.zone_id}"
    name = "www.dmathieu.com"
    type = "CNAME"
    ttl = "300"
    records = ["webredir.vip.gandi.net."]
}

I just have to push this to a private GIT repo (and backup the terraform.tfstate file in dropbox) to have a versionned configuration of my DNS which works with multiple providers.