AWS Bites Podcast

31. CloudFormation or Terraform?

Should I use CloudFormation or should I use Terraform instead? If you are just starting to write Infrastructure as Code (IaaC) you probably have this question. In this episode, we will discuss in detail how these two amazing pieces of technology compare against each other and what their features, weaknesses and strengths are. We will share our opinions based on our experience with these 2 technologies and guess what, for once we have a bit of clash of opinions! Can you guess who is in the Terraform camp and who is in the CloudFormation camp instead?

In this episode we mentioned the following resources:

Let's talk!

Do you agree with our opinions? Do you have interesting AWS questions you'd like us to chat about? Leave a comment on YouTube or connect with us on:

00:08:06

So a stack is essentially a collection of resources with its own state. And there's also something called stack sets, which is essentially the same stack applied across multiple accounts or regions. You also have things like nested stacks. So you can have a hierarchy of CloudFormation templates. And when you mentioned Terraform plan, there's a similar idea in Cloud formation called a change set. So you can create a change set and that's also created on the cloud side. And it's essentially a list of changes that will be applied. And then you can decide whether to execute that change set or not. You also mentioned rollbacks. So one of the things I like about CloudFormation is that it has automated rollbacks. So I think about more like when you're interacting with a database, you've got a transaction and within that transaction, you've got a series of changes and a CloudFormation update is very much like a transaction. And if one of those updates fails, CloudFormation will manage the rollback for you. And for that reason, it feels safer using CloudFormation because it's kind of AWS's responsibility to fulfill that rollback. Recently, you actually have support for removing or disabling rollbacks in development as well. So that makes the development process a bit handier, a bit faster. And you also mentioned one of the things that can happen with any of these tools is that manual changes, people can go in and make changes that aren't reflected in the stored state. And one of the newer features of CloudFormation is drift detection. So it'll let you know and track the state of resources against the template. So you can see what's changed compared to that state. That can be useful. It doesn't support all the resource types, but I think there's a growing set. There is support for information as well for importing existing resources. It's not something I would like to have to do very often because it's a little bit of a laborious process, but it's also a reasonably new feature where if you've got some resources that you created manually in the console, you can kind of adopt them into your CloudFormation stack. There's a lot of other new features as well, like hooks. So you can execute arbitrary code at different stages in the deployment life cycle. And there's this kind of other stuff as well. Like if you've got an auto scaling group, CloudFormation integrates with that as well and can do rolling deployments. I think one of the kind of last features I'd call out is that CloudFormation gives you very good secrets management. So it's well integrated with SSM, parameter store for secure secrets and also secrets manager. So you don't have to pass those around. They can be imported securely within the cloud side, within the CloudFormation service for you. And again, because it's JSON or YAML, it's fairly flat and declarative and not very dynamic. And that can be a benefit, but also a drawback. I know in Terraform, you have like loops. You can do count, loops up to account, like a for loop essentially. In CloudFormation, you don't have loops, but you do have conditions. So you can decide whether to include something or not based on the value of a parameter. And that parameter could come from inputs to the template, or it could come from a SSM parameter for you.

Eoin
00:11:12

Because it's an AWS service as well, I suppose it's worth calling out some of the integrations that CloudFormation already has with other AWS services. So if you're into code deploy for deploying to EC2 or Lambda, CloudFormation integrates well with that. So you can do rolling deployments there. Of course, it's integrated with IAM. So your CloudFormation actions are going to be done under a role that you can specify and control. And if you want to be able to deploy CloudFormation templates, give users the capability to deploy stuff from the console on demand, like if they need a bucket or whatever application you might want to deploy on demand, there's a service called Service Catalog that uses CloudFormation under the hood for that. So those are some integrations of note. And of course, you also have the tooling that's built on top of CloudFormation. I think I read somewhere recently that like 70% of CloudFormation is deployed using the serverless framework. Don't quote me on that. Something pretty high. Yeah. And AWS SAM is a similar tool that's also built on CloudFormation. And since we mentioned that with YAML and JSON, it's not very dynamic. Of course, you have the CDK, which we have covered in a previous episode in a lot of depth. And that's a programmatic imperative way of generating CloudFormation in your language of choice. There are some limitations in quotas because it's an AWS service. In terms of numbers, you can put 500 resources in a stack and you can have up to like 2000 stacks, which should be plenty for a given account. That number of resources was increased a couple of years ago, maybe even last year, but I've never, I definitely haven't reached the 500 resource limit because I tend to use small stacks. I prefer things that way. The template size itself can be 50K, but you can put it up on S3 and then you can use a template size of up to a megabyte. Which considering that's- One of the other important limitations, actually, just to mention it quickly, is that with CloudFormation, you cannot modify a resource that isn't within the stack. And that's an important one to be aware of. So if you've got an existing bucket and you wanted to add, like previously it was quite common, you'd want to create an application, but you wanted it to be a Lambda function to be triggered by a notification in S3 bucket. If you were trying to modify the bucket's notification configuration, you couldn't do that in a different stack. So you had all these workarounds in serverless framework that would create custom resources to fulfill that for you.

00:16:56

So that's a nice feature because basically by using the exact same syntax, there are very small differences, you get that modularity and it feels like importing functions in a programming language and just calling the functions. So that's something I really like from Terraform. But also there are other ways to extend Terraform. There is already a concept of provider. There are a lot of built-in providers like AWS, Azure, and all sorts of different providers. But of course, you can also create your own if you want to support, I don't know, any provider or any cloud service that is not natively supported. Or if you just want to do custom things to interact even with providers that are supported, but maybe using features that are not currently existing in the actual built-in providers. And another interesting thing that I used in the past and I think is not that uncommon is this idea of null resource, which is basically a way to say I'm not really defining a resource that Terraform itself needs to manage. It's more I want to have a hook in my provisioning steps to say this is kind of a virtual resource and I can define conditions like, I don't know, maybe when something else changes. And then with that condition, you can attach, for instance, a script or something else. And that way you can create mechanisms to say, okay, maybe before every deployment, if this particular condition happens, run a script that, I don't know, maybe tries to get an SSL certificate from somewhere and then use that certificate as part of your stack. So that's another, I suppose, easy enough way that you can create custom hooks into your Terraform deployments. In that term, how do we compare extensibility from Terraform to CloudFormation?

00:19:21

So you can create either like a single resource or multiple resources. And it's a bit like a CDK construct, but you're just doing it with declarative CloudFormation. There's a new thing called the CloudFormation registry, where you can then register those modules publicly. And another thing you can put into the CloudFormation registry is a CloudFormation resource type. And this is where you're going all full in on creating your own CloudFormation resource type. And it's a much more involved process. There is some tooling, there's this CloudFormation command line tool that you can use to bootstrap this and to publish it to the CloudFormation registry. But it's essentially like you're adding a feature into CloudFormation properly. So it includes validation, progress updates, all of the features you get with any CloudFormation resource type. I believe it's the same mechanism that CloudFormation internally uses for creating resources. And the difference between it and CloudFormation customer resources is that it's not running in your own Lambda, in your own AWS account. It's running in AWS, in their managed service. And there's something else called CloudFormation Macros, which allows you to do transformations and templating essentially. So people who have used AWS Sam might be familiar with the serverless transform, which allows you to create a Lambda function with just a few lines of code that actually uses the CloudFormation macro feature under the hood. And there's also another popular one called CloudFormation include, which is just for doing includes in your templates. And that's also using macros. But if I would recommend, if anyone is interested in learning more about creating custom things in CloudFormation and extending CloudFormation support where there's missing resources, then the Cloudanaut blog, we've mentioned them on the podcast before. You guys know a lot about CloudFormation and they've created, they've a really good podcast called Three and a Half Ways to Work Around Missing CloudFormation Support, which talks about all this stuff and more in depth. Yeah. So at this point, another topic that comes to mind is what about multi-account deployments?

00:27:36

You still need to explicitly say, I want to use this resource with this provider. So if you use, I don't know, an Azure function compared to a Lambda, there isn't any abstraction for you, but you can reuse the same HGL syntax and the same Terraform concept to provision both. It's going to be different code, but you have the same user experience. I hope that that summarizes my opinion and maybe to finish off with this episode, what we can do is give a quick mention to other tools that I personally haven't used, but I've heard them coming up more and more in conversation. And I think the main one is Pulumi, which is kind of a crossover between CDK and Terraform. And by that, I mean that it's like CDK, meaning that you use programming languages to actually define that infrastructure as code. So you get something a lot more dynamic and well integrated with your idea of choice. You don't need to learn a new language, but at the same time, it's multi-cloud. So where CDK is targeting only AWS, in quotes, because I think that that's going to be changing in the near future, but right now is really well-built only for AWS. Pulumi is already aiming to target a bunch of different cloud providers. And we already mentioned CDK as an alternative, but also SAM and serverless, which are built on top of cloud formation. So sometimes it can be convenient for you to use these higher level abstractions rather than just going straight to cloud formation, which might be a lot more lower level and verbose than using these other tools. And I think that concludes this episode. Do you have any final remark, Eoin?

Help us to make this transcription better! If you find an error, please submit a PR with your corrections.