Terraform Apps and Infra 7 - Abstraction

Introduction

  • Terraform as a tool is cloud agnostic (it will support anything that exposes its API and has enough developer support to create a “provider” for it).
  • Terraform by itself will not natively abstract this at all, please consider if this is a good idea at all unless you have a really good use case.
    • If you did need to do this you would need to:
      • build a bunch of modules on top of things that abstracts the cloud layer from the module users.
      • allow them to specify the cloud provider as a variable (potentially controllable from some outside script).
  • You can check the registry.

Example: abstract when there is resource parity

Original DNS modules

Google Cloud DNS

  • modules/google/dns/record/main.tf

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    variable "count" = {}

    variable "domain_name_record" = {}
    variable "domain_name_zone" = {}
    variable "domain_name_target" = {}

    resource "google_dns_record_set" "frontend" {
    count = "${variable.count}"
    name = "${var.domain_name_record}.${var.domain_name_zone}"
    type = "CNAME"
    ttl = 300

    managed_zone = "${var.domain_name_zone}"

    rrdatas = ["${var.domain_name_target}"]
    }

AWS

  • modules/aws/dns/record/main.tf

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    variable "count" = {}

    variable "domain_name_record" = {}
    variable "domain_name_zone" = {}
    variable "domain_name_target" = {}

    data "aws_route53_zone" "selected" {
    count = "${variable.count}"
    name = "${var.domain_name_zone}"
    }

    resource "aws_route53_record" "www" {
    count = "${variable.count}"
    zone_id = "${data.aws_route53_zone.selected.zone_id}"
    name = "${var.domain_name_record}.${data.aws_route53_zone.selected.name}"
    type = "CNAME"
    ttl = "60"
    records = [${var.domain_name_target}]
    }

Generic inluding both module code

  • modules/generic/dns/record/main.tf

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    variable "cloud_provider" = { default = "aws" }

    variable "domain_name_record" = {}
    variable "domain_name_zone" = {}
    variable "domain_name_target" = {}

    module "aws_dns_record" {
    source = "../../aws/dns/record"
    count = "${var.cloud_provider == "aws" ? 1 : 0}"
    domain_name_record = "${var.domain_name_record}"
    domain_name_zone = "${var.domain_name_zone}"
    domain_name_target = "${var.domain_name_target}"
    }

    module "google_dns_record" {
    source = "../../google/dns/record"
    count = "${var.cloud_provider == "google" ? 1 : 0}"
    domain_name_record = "${var.domain_name_record}"
    domain_name_zone = "${var.domain_name_zone}"
    domain_name_target = "${var.domain_name_target}"
    }