blog > infrastructure-as-code-iac-part-3-detailed-tool-analysis

Infrastructure as Code (IaC) Part 3: Detailed Tool Analysis

by Ulrich Van Rooyen
Published on: 2/26/2025

Introduction

In this, the third blog in this series on IaC, we will be looking at and diving deep into some tools that allows it all to be possible. In the previous parts of this blog series, we went into detail regarding different implementation strategies, scaling out, and core concepts of IaC. Today we are going to go into detail on three popular tools for IaC – Terraform, Ansible and AWS CloudFormation. For each of the tools, we will break down how they work, their unique features available, as well as a few use cases for them. Whether you are new to IaC, or looking to refine your toolkit, this blog will help you make informed decisions about your infrastructure management strategy with some valuable insights. For the examples of each tool, we will be using VS Code as our IDE.

Terraform

Terraform is an Infrastructure as Code (IaC) tool that allows users to define and provision infrastructure using a declarative configuration language called HashiCorp Configuration Language (HCL). By focusing on the desired state rather than procedural steps, Terraform simplifies infrastructure management, reducing manual intervention and human error

Some of the key Features of Terraform include state management, modularity and multi-cloud support. Terraform maintains a state file, which acts as the single source of truth for your infrastructure. This file enables Terraform to track resource dependencies and ensure consistent management across teams. Terraform supports breaking down complex infrastructure into reusable modules. This modular approach simplifies configuration management and allows organizations to share and version control infrastructure components effectively. With its provider ecosystem, Terraform enables management of resources across various cloud platforms. Users can implement hybrid and multi-cloud architectures seamlessly, regardless of the underlying provider.

Let’s take a look at a practical Terraform example that creates an AWS environment with a VPC, public subnets, and EC2 instances.

practical Terraform example that creates an AWS environment with a VPC, public subnets, and EC2 instances.
  • The provider block (Lines 2-10) specifies AWS as the cloud provider, setting the default region for resource creation and defining global tags applied to all resources. It also establishes the authentication context for AWS API calls.
  • The VPC resource (Lines 13-21) defines the network foundation with a specific CIDR range, enabling DNS support for instances within the network.
  • The count parameter (Line 25), within the subnet resource block (Lines 24-33), allows creating multiple subnets dynamically, reducing code duplication and enabling efficient scaling.
  • User data (Lines 42-49), within the EC2 instance resource block (Lines 36-54), automates instance setup during launch by running bootstrap scripts. For example, the script shown installs and configures an HTTP server.

Advantages of Terraform include:

  • Scalability and Reusability
    • Modules enable code reuse across projects
    • Count and for_each parameters support dynamic resource creation
    • State management ensures consistency at scale
  • Provider Ecosystem
    • Support for major cloud providers (AWS, Azure, GCP)
    • Extensive collection of available resources
    • Regular updates and improvements
  • HashiCorp Integration
    • Terraform Enterprise for enterprise features

Limitations include:

  • Learning Curve
    • HCL syntax requires time to master
    • Understanding provider-specific resources
    • Complex state management concepts
  • State File Dependencies
    • State files must be properly managed
    • Remote state storage needed for team collaboration
    • State file corruption can be problematic

Best Practices when using Terraform

  • State Management
    • Use remote state storage (S3, Terraform Cloud)
    • Implement state locking
    • Backup state files regularly
  • Code Organization
    • Use modules for reusable components
    • Follow a consistent directory structure
    • Implement proper variable management
  • Security
    • Use variables for sensitive information
    • Implement proper IAM roles
    • Regular security audits of infrastructure code

Ansible

Ansible is an open-source automation tool that simplifies configuration management, application deployment, and task automation. It uses YAML for its playbooks, making it human-readable and easy to understand. Unlike other configuration management tools, Ansible is agentless and uses SSH for communication with managed nodes.

Ansible uses inventory files to define and organize managed hosts. An inventory file in Ansible is like an address book for your infrastructure. It defines which servers you want to manage and how they’re organized. Let us take a look at an example of an inventory file in YAML:

  • Server Groups (denoted by [group_name])
    • [webservers] groups your web servers together
    • [databases] groups your database servers together
    • You can reference these groups in playbooks using their names
  • Group Hierarchy (using :children)
    • [production:children] creates a parent group called “production”
    • It includes both webservers and databases groups
    • This lets you run playbooks against all production servers at once
  • Group Variables (using :vars)
    • [production:vars] sets variables for all servers in the production group
    • These variables are automatically available to all servers in that group
    • Useful for environment-specific settings

This structure allows you to:

  • Organize servers logically by their role
  • Apply configurations to specific groups of servers
  • Share variables across related servers
  • Create hierarchical relationships between groups

http://example of an Ansible playbook that sets up a web application environmentA playbook in Ansible is like a set of detailed instructions or a recipe that defines what you want to set up on your servers. It’s written in YAML format and contains a list of tasks that Ansible should execute in order. Here’s a comprehensive example of an Ansible playbook that sets up a web application environment:

example of an Ansible playbook that sets up a web application environment
example of an Ansible playbook that sets up a web application environment

Let’s break down this example:

  • Hosts and Privilege escalation (Lines 3-4)
    • hosts specifies which inventory group to target
    • become: true enables privilege escalation
    • This is essential for tasks requiring root privileges
  • Variables (Lines 5-14)
    • These define reusable values
    • Allows support of environment-specific configurations
    • Able to be overridden at multiple levels
  • Tasks (Lines 16-73)
    • Tasks define actions to be performed, such as installing required packages
    • Makes use of Ansible modules such as package, file and service.
    • Supports tags that can be used for selective execution
  • Handlers (Lines 75-84)
    • They are triggered by notifications from tasks
    • Only run when notified and only once per playbook
    • Perfect to use for service restarts and reloads

Advantages of Ansible:

  • Agentless Architecture
    • No need to install agents on managed nodes
    • Simpler maintenance and security
    • Lower resource overhead
  • Human-Readable Syntax
    • YAML-based playbooks
    • Clear and intuitive structure
    • Easy to learn and maintain
  • Extensibility
    • Large collection of built-in modules
    • Community-contributed roles
    • Custom module development

Limitations include:

  • Performance
    • Sequential task execution by default
    • Can be slow with large inventories
    • Network overhead for each task
  • Cloud Infrastructure
    • Limited native cloud resource management
    • Better suited for configuration than provisioning

Some best practices to follow when using Ansible:

  • Organization
    • Use roles for reusable configurations
    • Implement proper variable precedence
    • Maintain consistent directory structure
  • Security
    • Use vault for sensitive data
    • Implement proper SSH key management
    • Regular security audits
  • Performance
    • Use async tasks for long-running operations
    • Implement proper error handling
    • Use tags for selective execution

AWS CloudFormation

AWS CloudFormation is a native AWS service that allows you to define your infrastructure as code using either JSON or YAML templates. It enables you to create, update, and delete AWS resources in a consistent and automated way. At the centre of CloudFormation, there is the template structure. This template consists of a few main sections in regard to the definition/configuration of your infrastructure. Let us break down a practical example of a CloudFormation template.

The First main section of the template would be the Parameters (Lines 4-25). This section enables template customisation, support for different parameter types and can also include validation. This block can include parameters such as the environment name and instance types, allowing for customisation of values under these parameters such as the description, type and even a default value.

The next main section is the Resources (Lines 27-62) section. In this section, we define AWS resources that will be created such as a security group, or a launch template for an EC2 instance. We can also specify properties for each of these resources, some of the properties one can set for a security group include the group description, VpcId and different IP Protocols on different ports. Other properties that can be set, such as on a launch template for an EC2 instance include properties such as the ImageId, instance type and even security group IDs. The resource block also supports dependencies between resources, such as creating the security group, then using that group when defining an EC2 instance.

Another main section done within a CloudFormation is the Outputs (Lines 63-74). This block exposes important information such as the Security group ID or the Load Balancers DNS. This section can be used by other ‘stacks’ (within other templates). This section of the template can also be highly useful for the documentation of the template file.

Advantages of using AWS CloudFormation:

  • AWS Integration
    • Native AWS service
    • Automatic resource dependency handling
    • Built-in rollback capabilities
  • Version Control
    • Templates can be version controlled
    • Changes can be reviewed
    • History of infrastructure changes
  • Automation
    • Consistent deployments
    • Automated rollbacks
    • Stack update capabilities

Limitations of AWS CloudFormation include:

  • AWS-Only
    • Limited to AWS resources
    • No multi-cloud support
    • Vendor lock-in concerns
  • Flexibility
    • Less flexible than Terraform
    • More complex state management
    • Limited module system

Best Practices to follow when using AWS CloudFormation:

  • Template Organization
    • Use clear parameter names
    • Group related resources
    • Include meaningful descriptions
  • Security
    • Use specific security group rules
    • Implement proper IAM roles
    • Avoid hardcoding sensitive data
  • Scalability
    • Use Auto Scaling Groups
    • Implement proper health checks
    • Configure appropriate alarms
FeatureTerraformAnsibleCloudFormation
Primary use caseInfrastructure provisioningConfiguration management    AWS resource management
LanguageHCL (HashiCorp Configuration Language)               YAML    JSON/YAML
Cross-PlatformYes, supports multi-cloud and hybrid environments   Yes, works with various clouds and systems        No, exclusively for AWS
Ease of LearningModerate, due to HCL syntax and state management    Easy, thanks to simple YAML syntax      Moderate, templates can become complex
Community supportHigh, with extensive documentation and ecosystem          High, with wide community and Red Hat backingModerate, primarily supported by AWS forums  

Conclusion

The choice of an Infrastructure as Code (IaC) tool depends largely on your specific project requirements and organizational needs. Terraform stands out for its multi-cloud capabilities and modular design, making it ideal for diverse environments. Ansible shines in configuration management with its user-friendly YAML syntax and agentless architecture, simplifying automation tasks. Meanwhile, AWS CloudFormation excels in AWS-specific resource management with deep native integration and automated deployment features.

Each tool has its strengths and limitations, from Terraform’s learning curve to Ansible’s performance in large-scale environments and CloudFormation’s lack of multi-cloud support. By understanding these nuances, you can select the tool or combination of tools that best align with your infrastructure management strategy. With the right approach, these tools empower teams to deliver scalable, reliable, and efficient infrastructure solutions.

Infrastructure as Code (IaC) Part 4 – Advanced Best Practices >>

WRITTEN BY

Ulrich Van Rooyen