Comparison IaC Tools: Terraform ,AWS CloudFormation and AWS CDK

Roman Ceresnak, PhD
CodeX
Published in
12 min readDec 10, 2023

As the digital landscape evolves, businesses worldwide are leveraging innovative technologies to enhance efficiency while ensuring security and cost-effectiveness. One such revolution in operational adaptability is the advent of Infrastructure as a Service (IaC) technologies like Terraform, AWS CloudFormation, and AWS CDK. These tools are redefining the concept of infrastructure management, offering unprecedented flexibility and control in how companies manage their IT resources.

Understanding Terraform, AWS CloudFormation, and AWS CDK:

Terraform, AWS CloudFormation, and AWS CDK are groundbreaking because they automate the provisioning and management of infrastructure, allowing businesses to define their infrastructure as code. This technological advancement means that organizations can manage their infrastructure with the same rigor and codification as their software, facilitating a new level of efficiency, scalability, and disaster recovery potential.

Terraform:

Terraform

Terraform, developed by HashiCorp, is an open-source tool that allows users to define and provision a datacenter infrastructure using a high-level configuration language known as HashiCorp Configuration Language (HCL), or optionally JSON. Terraform generates an execution plan describing what it will do to reach the desired state and then executes it to build the described infrastructure. As it creates an execution plan, Terraform can determine what changes are necessary to achieve the desired state, and in what order these changes should be applied.

Key Aspects of Terraform:

Infrastructure as Code (IaC): Terraform allows you to define your infrastructure using a high-level configuration language called HashiCorp Configuration Language (HCL), or JSON. This code-based approach to infrastructure management automates the process of infrastructure provisioning, leading to faster deployment, fewer errors, and higher consistency.

Declarative Configuration Files: In Terraform, you describe your desired infrastructure state using configuration files. Terraform then automatically determines the actions required to achieve that state, allowing for predictable and transparent infrastructure management.

Provider Ecosystem: Terraform can manage a wide variety of resources including physical servers, networks, and databases, as well as cloud services. It achieves this through a rich ecosystem of providers, which are plugins that interface with APIs of service providers, such as AWS, Microsoft Azure, Google Cloud Platform, and many others.

Plan and Apply Workflow: Terraform follows a consistent workflow with two key steps — ‘plan’ and ‘apply’. ‘Terraform plan’ creates an execution plan, which shows what Terraform will do when you run ‘Terraform apply’. This predictability helps prevent deployment surprises and errors.

State Management: Terraform maintains a state file which is a snapshot of the current state of the infrastructure. This state allows Terraform to identify changes and perform incremental updates, ensuring that the real-world infrastructure matches the configuration.

Modularity and Reusability: Through the use of modules, Terraform enables users to reuse and share components, promoting efficient and maintainable infrastructure code. These modules can be stored and shared via a Terraform module registry, enhancing collaboration and standardization.

Immutable Infrastructure: Terraform encourages an immutable infrastructure approach, where changes are made by replacing the old version with a new one, rather than updating the existing infrastructure. This reduces the risk of configuration drift and unintended side effects.

Multi-Cloud Deployment: With Terraform, organizations are not locked into a single cloud provider. It allows for managing resources across multiple clouds, making it an ideal tool for hybrid and multi-cloud strategies.

Community and Collaboration: Terraform’s open-source nature has fostered a robust community that contributes to its continuous improvement. Additionally, HashiCorp offers a commercial version, Terraform Enterprise, which provides advanced features for teamwork and governance.

Use Cases for Terraform:

  • Automating Cloud Infrastructure: Quickly provision and manage cloud resources.
  • Multi-Cloud Strategy Implementation: Seamlessly manage infrastructure across various cloud platforms.
  • Self-Service Infrastructure: Enable teams to spin up their own environments within governance guidelines.
  • Disaster Recovery: Easily replicate infrastructure for backup and recovery purposes.
  • Cost Management: Efficiently scale infrastructure to manage costs.

Example of the code:

resource "aws_instance" "example" {
ami = "ami-0c5c490595704e643"
instance_type = "t2.micro"
tags = {
Name = "example-instance"
}
}

This code will create an EC2 instance in the AWS region that you are currently using. The ami attribute specifies the AMI ID of the image to use, and the instance_type attribute specifies the type of instance to create. The tags attribute specifies a map of tags to apply to the instance.

To apply this Terraform configuration, you would save the code as a file named main.tf and then run the following command:

terraform apply

This will create the EC2 instance in your AWS account.

Here is another example of Terraform code that creates a VPC, subnet, and route table in AWS:

resource "aws_vpc" "example" {
cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "example" {
vpc_id = aws_vpc.example.id
cidr_block = "10.0.1.0/24"
}

resource "aws_route_table" "example" {
vpc_id = aws_vpc.example.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.example.id
}
}

resource "aws_internet_gateway" "example" {
vpc_id = aws_vpc.example.id
}

This code will create a VPC with a subnet and a route table. The VPC will have a CIDR block of 10.0.0.0/16, the subnet will have a CIDR block of 10.0.1.0/24, and the route table will use the default gateway provided by the internet gateway.

To apply this Terraform configuration, you would save the code as a file named vpc.tf and then run the following command:

terraform apply

In conclusion, Terraform is a cornerstone technology for modern infrastructure management, offering agility, consistency, and a breadth of capabilities that empower organizations to efficiently manage their IT infrastructure in an increasingly complex digital landscape.

AWS CloudFormation:

AWS CloudFormation

AWS CloudFormation is a service provided by Amazon Web Services that gives developers and businesses an easy way to create a collection of related AWS and third-party resources, and provision and manage them in an orderly and predictable fashion. Users can use YAML or JSON to model and provision all the resources needed for their applications across all regions and accounts. This provides a single source of truth for your AWS infrastructure.

Key Features of AWS CloudFormation:

Template-Driven Resource Provisioning: CloudFormation allows users to define their AWS infrastructure in text files or templates, using either JSON or YAML format. These templates describe the AWS resources and their configurations, enabling CloudFormation to automatically provision and configure the resources as described.

Declarative Syntax: The templates use a declarative syntax, which means users only need to specify what resources are required, and CloudFormation handles the creation and arrangement of these resources. This removes the need for manual, error-prone processes.

Resource Management: CloudFormation manages the complete lifecycle of resources: it can create, update, and delete resources as defined in the templates. This ensures that the infrastructure stays aligned with the defined configuration.

Change Management and Rollbacks: When changes are made to a template, CloudFormation updates the resources in a controlled manner. If any errors are detected during an update, it can automatically rollback to the previous state, minimizing downtime and issues.

Stacks: Resources in CloudFormation are organized into “stacks”, which are collections of resources that can be managed as a single unit. This allows for organized and modular management of infrastructure components.

Nested Stacks and Cross-Stack References: CloudFormation supports nested stacks — stacks that are linked to other stacks. This feature allows for creating complex architectures that are easier to manage and update. Cross-stack references enable sharing of outputs between stacks, enhancing modularity.

AWS Integration: Being an AWS-native service, CloudFormation is designed to work seamlessly with a wide range of AWS services. This integration ensures high compatibility and efficiency in AWS environments.

Custom Resources: If CloudFormation doesn’t natively support a specific AWS resource or property, custom resources can be used. These are custom-defined extensions that can call AWS Lambda functions to manage any resource that CloudFormation does not support directly.

Drift Detection: CloudFormation can detect “drift”, the difference between the expected configuration of a stack and its actual configuration. This feature helps in maintaining consistency and compliance.

Template Validation and Linting: Templates can be validated within CloudFormation for syntax and best practices before deployment, reducing errors and improving reliability.

Common Use Cases for AWS CloudFormation:

  • Infrastructure Replication: Easily replicate entire environments for development, testing, or disaster recovery purposes.
  • Environment Consistency: Ensure that all environments, from development to production, are consistent and configured as intended.
  • Automated Infrastructure Deployment: Automate the provisioning and management of AWS infrastructure, reducing manual effort and increasing efficiency.
  • Compliance and Governance: Enforce compliance and governance standards by defining and managing infrastructure through code.
  • Resource Dependency Management: Automatically handle dependencies between resources during creation, updates, or deletion.

Example of the code:

AWSTemplateFormatVersion: '2010–09–09'
Description: Create an EC2 instance
Resources:
Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
Tags:
- Key: Name
Value: example-instance

This code will create an EC2 instance in the AWS region that you are currently using. The InstanceType property specifies the type of instance to create, and the Tags property specifies a map of tags to apply to the instance.

To apply this AWS CloudFormation template, you would save the code as a file named template.yaml and then run the following command:

aws cloudformation create-stack — template-body file://template.yaml

This will create the EC2 instance in your AWS account.

Here is another example of AWS CloudFormation code that creates a VPC, subnet, and route table in AWS:

AWSTemplateFormatVersion: '2010–09–09'
Description: Create a VPC, subnet, and route table
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
Subnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
InternetGateway:
Type: AWS::EC2::InternetGateway
InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Route:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref RouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway

This code will create a VPC with a subnet and a route table. The VPC will have a CIDR block of 10.0.0.0/16, the subnet will have a CIDR block of 10.0.1.0/24, and the route table will use the default gateway provided by the internet gateway.

To apply this AWS CloudFormation template, you would save the code as a file named vpc_template.yaml and then run the following command:

aws cloudformation create-stack — template-body file://vpc_template.yaml

In summary, AWS CloudFormation is a powerful tool for organizations leveraging AWS services, providing a comprehensive, reliable, and efficient way to manage cloud infrastructure. Its ability to automate complex deployments and handle the entire lifecycle of AWS resources makes it an essential component of a robust cloud strategy.

AWS CDK (Cloud Development Kit):

The AWS Cloud Development Kit (AWS CDK) is a revolutionary cloud infrastructure provisioning tool that streamlines the process of defining cloud resources in a programmatic and familiar way. As part of the growing trend of Infrastructure as Code (IaC), AWS CDK allows developers to define their cloud resources using popular programming languages, merging the world of software development with cloud infrastructure management. This innovative approach is reshaping how businesses deploy and manage their AWS environments, offering a blend of flexibility, efficiency, and precision.

Key Features of AWS CDK:

Programming Language Support: AWS CDK supports several mainstream programming languages, including TypeScript, JavaScript, Python, Java, and C#. This allows developers to use the languages they are already familiar with to define and manage cloud infrastructure.

High-Level Constructs (L1, L2, and L3 Constructs): AWS CDK provides three levels of constructs — L1 (CFN Resources), L2 (AWS Constructs), and L3 (Patterns). L1 constructs are direct representations of AWS CloudFormation resources, L2 constructs offer sensible defaults and reduce boilerplate, and L3 constructs are higher-level abstractions for complete AWS solutions.

Integration with AWS CloudFormation: Underneath, AWS CDK uses AWS CloudFormation for resource provisioning. This means that CDK applications are converted into CloudFormation templates, benefiting from CloudFormation’s robustness and stability.

Imperative Code for Infrastructure Definition: Unlike traditional IaC tools that use declarative syntax, AWS CDK allows developers to define infrastructure using imperative programming constructs. This can lead to more expressive, dynamic, and reusable infrastructure code.

Reusable Components (Construct Libraries): AWS CDK provides a rich set of construct libraries that represent AWS services, allowing developers to share and reuse abstractions for cloud components, leading to more efficient and error-free infrastructure development.

Synthesis and Deployment: AWS CDK applications are synthesized into AWS CloudFormation templates and can be directly deployed to AWS, simplifying the deployment process.

Contextual and Environment-Aware: CDK applications can be context-aware, meaning they can adapt their behavior based on the environment they are being deployed in, enabling more dynamic and flexible infrastructure setups.

Testing and Validation: AWS CDK supports unit and integration testing of the infrastructure code, ensuring that infrastructure deployments are reliable and less prone to errors.

Common Use Cases for AWS CDK:

  • Rapid Development and Prototyping: Leverage familiar programming languages for quick prototyping and development of cloud infrastructure.
  • Complex Infrastructure Management: Manage complex cloud architectures more effectively with imperative programming, creating modular and reusable components.
  • Custom Resource Creation: Easily define custom AWS resources and extend AWS CDK’s capabilities.
  • Environment-Agnostic Deployments: Create infrastructure setups that adapt to different deployment environments (development, staging, production).
  • Streamlining DevOps Practices: Integrating infrastructure management into application development workflows, enhancing collaboration between development and operations teams.

Example of the code:

import * as cdk from '@aws-cdk/core';
import * as ec2 from '@aws-cdk/aws-ec2';

export class MyStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

const instance = new ec2.Instance(this, 'exampleInstance', {
ami: ec2.LookupAmiConfig.fromAsset('ami-0c5c490595704e643'),
instanceType: 't2.micro',
tags: {
Name: 'My EC2 Instance'
}
});
}
}

This code will create an EC2 instance in the AWS region that you are currently using. The ami property specifies the AMI ID of the image to use, and the instanceType property specifies the type of instance to create. The tags property specifies a map of tags to apply to the instance.

To deploy this CDK stack, you would save the code as a file named mystack.ts and then run the following command:

cdk deploy

This will create the EC2 instance in your AWS account.

Here is an example of AWS CDK code that creates a VPC, subnet, and route table in AWS:

import * as cdk from '@aws-cdk/core';
import * as ec2 from '@aws-cdk/aws-ec2';
export class MyStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);

const vpc = new ec2.Vpc(this, 'exampleVpc', {
cidrBlock: '10.0.0.0/16'
});

const subnet = new ec2.Subnet(this, 'exampleSubnet', {
vpc: vpc,
cidrBlock: '10.0.1.0/24'
});

const internetGateway = new ec2.InternetGateway(this, 'exampleInternetGateway');

const internetGatewayAttachment = new ec2.VPCGatewayAttachment(this, 'exampleInternetGatewayAttachment', {
vpc: vpc,
internetGatewayId: internetGateway.id
});

const routeTable = new ec2.RouteTable(this, 'exampleRouteTable', {
vpc: vpc
});

const route = new ec2.Route(this, 'exampleRoute', {
routeTable: routeTable,
destinationCidrBlock: '0.0.0.0/0',
gatewayId: internetGateway.id
});

const subnetRouteTableAssociation = new ec2.SubnetRouteTableAssociation(this, 'exampleSubnetRouteTableAssociation', {
subnetId: subnet.id,
RouteTableId: routeTable.id
});
}
}

This code will create a VPC with a subnet and a route table. The VPC will have a CIDR block of 10.0.0.0/16, the subnet will have a CIDR block of 10.0.1.0/24, and the route table will use the default gateway provided by the internet gateway.

To deploy this CDK stack, you would save the code as a file named mystack.ts and then run the following command:

cdk deploy

In conclusion, AWS CDK represents a significant leap in the field of cloud infrastructure management. By bridging the gap between software development and cloud resource provisioning, it opens up new possibilities for efficient, scalable, and reliable cloud infrastructure deployment. For developers already working within the AWS ecosystem, AWS CDK offers an intuitive and powerful tool to harness the full potential of AWS services.

Common use cases for Terraform, AWS CloudFormation, and AWS CDK:

The versatility of Terraform, AWS CloudFormation, and AWS CDK is evident through a myriad of use cases applicable to various business scenarios, regardless of size or sector. These include:

  • Infrastructure Automation: Automating the provisioning of servers, databases, networks, and other infrastructure components.
  • Configuration Management: Managing the configuration of the provisioned infrastructure.
  • Resource Scheduling: Automatically starting or stopping resources based on usage patterns to optimize costs.
  • Multi-cloud Deployment: Using Terraform for managing infrastructure across multiple cloud providers.
  • Scalability and High Availability: Ensuring that the infrastructure scales as per the demand and is highly available.

Conclusion:

Each of these technologies addresses different aspects of cloud infrastructure management. Terraform is known for its extensive multi-cloud support, AWS CloudFormation excels in stability and integration within AWS services, and AWS CDK offers an unprecedented level of flexibility and developer-friendliness. The choice between them depends on specific project requirements, existing infrastructure, team expertise, and the strategic goals of the organization.

Ultimately, the decision to use Terraform, AWS CloudFormation, or AWS CDK should align with the business’s cloud strategy, taking into consideration factors like cloud provider preferences, team skill sets, and the desired level of control and automation in managing cloud resources.

--

--

Roman Ceresnak, PhD
CodeX
Writer for

AWS Cloud Architect. I write about education, fitness and programming. My website is pickupcloud.io