Is Terraform really cloud agnostic?

Hi,

Does Terraform support easy transition from one cloud provider to another? For example OpenStack to AWS, without having to rewrite all the configuration files?

I’m taking this course because my team is considering switching from OpenStack (in our own organisation data centre) to an external cloud provider (AWS, GCP, etc.). This is part of a bigger vision of DevOps and CI/CD which requires us to automate our infrastructure creation and management, hence the interest in Terraform and Kubernetes.

When I first heard of Terraform, one of the attractive features seemed to be the ability to write infrastructure in a cloud agnostic way. Perhaps naively I thought it meant that I could write one set of files that could then be used to deploy our infrastructure on any cloud provider (OS, AWS, GCP, etc.).

However, now that I am learning a bit more about Terraform, this seems less straight forward. For example, if I want to create a web server, I need to write different *.tf files depending on the cloud provider I’m targeting.

For example, for AWS I need to define an aws_instance resource, and specify things like an ami code, etc. All of those are AWS specific and require understanding of how the Amazon platform works. If I want the same infrastructure on OpenStack or Azure, I have to rewrite all of my Terraform files. There is no automatic conversion between providers is there?

If that is correct, in what way does Terraform claim to be cloud agnostic? Am I missing something here?

Hi @ds33s,

Terraform is cloud-agnostic in that it works with multiple cloud providers. Terraform enables developers to maintain the same workflow when provisioning resources across cloud/infrastructure providers.

The following resources should help to explain Terraform’s approach to multi-cloud provisioning in more detail.


Disclaimer: I do not work for HashiCorp.

TL;DR
@ds33s you will have to write your .tf files specific to the cloud provider, yes.
I would still say Terraform is cloud agnostic. :slightly_smiling_face::slightly_smiling_face::slightly_smiling_face:

Longer version:
There can be some concept of mapping, i.e X in AWS means Y in Azure, etc. but overall there are differences not only in the properties but also the features, so to have a single definition for multiple clouds would get a bit tricky.
What you are asking is quite imaginable for simple resources like EC2 instances, but quite different, say for Lambda.
That said, there are Terraform modules which can help you to get started quickly, before you deep dive into specific resources.

HTH,
Shantanu Gadgil

Hi @blake,

The features of various infrastructure products are not entirely equivalent, and Terraform’s providers to expose all of the details of the underlying systems so that you can decide for yourself how to abstract over them – if you need to do that at all – to create a platform that meets your needs.

Terraform’s modules concept allows you to create and share abstractions to allow similar usage patterns across multiple platforms, but Terraform does not provide those abstractions itself because creating abstractions requires deciding which functionality is important and which functionality is unimportant in order to present a common set of functionality.

The module composition techniques are the primary way to create your own abstractions. The section of that guide titled Multi-cloud Abstractions illustrates that using DNS as an example: there are lots of vendors providing managed DNS services with different combinations of value-add features, but as module authors we can pick a common core of standard DNS functionality that all of these vendors can offer and then users of those modules can switch between DNS vendors just by swapping to a different module with a similar interface.

The virtual compute level of abstraction (EC2, in Amazon’s world) is generally not a good level to create an abstraction because at that layer there are still many vendor-specific implementation details visible. For example, the EC2 VPC model of networking and the Google Cloud Platform model of networking are similar but not fully compatible, making it hard to create a usable abstraction at that level. In order to be able to switch easily between vendors or use multiple vendors together we will generally need to raise the level of abstraction to hide those differing details, and a Kubernetes cluster is a good example of an abstraction over compute resources: there are many hosted and self-managed implementations of it on different platforms, all of which offer a common API and common set of capabilities.

Therefore you could choose to create your abstraction layer in terms of Kubernetes by writing a set of modules that each deploy a Kubernetes cluster with one particular vendor, and then write the rest of your configurations to work with the Kubernetes provider against the API hostname produced by any of those vendor-specific Kubernetes modules.

In the end though, that decision to use Kubernetes has consequences of its own, and so Terraform won’t make it for you. You might prefer to design your abstractions a different way to make different tradeoffs. Terraform is unopinionated about these decisions, instead just aiming to give you a language to express those abstractions and a common workflow regardless of which specific technology choices you make.

1 Like

Surely, you meant to promote Nomad rather than Kubernetes, to facilitate the “cloud agnostic” workflows, right!?! :rofl: :joy: :rofl: :joy: