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 example of how I can launch a VPC with some subnets, some instances, some ELB's, and a few databases in either AWS or Azure using a single tf
file.
Does any one have an example of that?
Terraform is cloud-agnostic and allows a single configuration to manage multiple providers and handle cross-cloud dependencies.
Yes, Terraform is cloud agnostic, in the sense that it can be used to run on almost every cloud provider there is.
Supported Infrastructure Terraform can help with multi-cloud by having one workflow for all clouds. The infrastructure Terraform manages can be hosted on public clouds like Amazon Web Services, Azure, and Google Cloud Platform, or on-prem in private clouds such as OpenStack, VMWare vSphere, or CloudStack.
“A business is cloud-agnostic when the company IT systems are not locked into a single cloud vendor or do not rely on one cloud provider's proprietary services,” explains Bailey. “Typically, services are spread between multiple cloud vendors to preserve and ensure the uptime of critical applications.”
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):
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}"]
}
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}]
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With