How to use Terraform in a cloud agnostic way

前端 未结 3 1079

I have seen many examples on how to use Terraform to launch AWS resources. I have also seen many claims that Terraform is cloud agnostic.

What I have not seen is an

3条回答
  •  一生所求
    2020-12-06 05:52

    While Terraform as a tool is cloud agnostic (in that it will support anything that exposes its API and has enough developer support to create a "provider" for it), Terraform itself will not natively abstract this at all and I'd seriously consider whether 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 and just allow them to specify the cloud provider as a variable (potentially controllable from some outside script).

    As a basic example to abstract DNS you might have something like this (untested):

    modules/google/dns/record/main.tf

    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}"]
    }
    

    modules/aws/dns/record/main.tf

    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}]
    }
    

    modules/generic/dns/record/main.tf

    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}"
    }
    

    Obviously this will get complicated pretty fast but it does mean that you can expose the "generic" module to others and allow them to use the abstractions you are building on things. How you cope with things where there isn't feature parity between different clouds is a whole separate question and probably not best suited for StackOverflow.

提交回复
热议问题