Getting Started with Infrastructure as Code (IaC): Terraform
Tags: terraform, cloud, devops, iac
Published: 2023-04-11 23:27:35


In my previous [article](https://dev.to/umoren/an-introduction-to-devops-principles-and-practices-14bl), I introduced Infrastructure as Code (IaC) as a key principle of DevOps and likened it to creating a recipe for setting up a computer system. To provide a more technical definition, HashiCorp, the company behind Terraform, describes IaC as infrastructure components (CPUs, memory, disk, firewalls, etc.) defined as code within definition files.

As the backbone of the DevOps movement, IaC brings a host of benefits, including increased efficiency, consistency, and collaboration between DevOps teams. By adopting IaC, teams can automate the provisioning and management of infrastructure, making it easier to scale and adapt to changing needs.

Infrastructure as Code (IaC) plays a critical role in DevOps by streamlining the process of managing and provisioning infrastructure. IaC allows for increased efficiency, collaboration, and automation by treating infrastructure like software code. Here are some key benefits of IaC in DevOps:

**Automation**: With IaC, you can create reusable templates to automate the provisioning and management of your infrastructure. This reduces manual intervention and minimizes the risk of human error, ultimately leading to more reliable and consistent environments.

**Version control**: IaC allows you to store your infrastructure definitions in version control systems like Git, making it easier to track changes, roll back to previous configurations, and collaborate with team members.

**Consistency:** IaC ensures that your infrastructure is consistent across different environments, such as development, testing, and production. This consistency helps avoid configuration drift and makes identifying and fixing issues easier.

**Scalability:** IaC simplifies scaling your infrastructure up or down as needed. You can easily replicate your infrastructure setup across multiple cloud regions or accounts, ensuring that your resources are available when and where they're needed.

**Cost savings:** By automating repetitive tasks and reducing the risk of human error, IaC can help you save time and money. Additionally, IaC enables you to manage your cloud resources better and optimize costs by quickly spinning up or tearing down resources based on demand.

In this article, I'll dive deeper into Infrastructure as Code, focusing on two widely-used IaC tools: Terraform and CloudFormation. I'll explore their features, similarities, and differences to help you decide which tool best suits your needs.

## Terraform

Terraform is an open-source Infrastructure as Code (IaC) tool that allows you to define, manage, and provision cloud infrastructure using a simple, human-readable language called HashiCorp Configuration Language (HCL). With Terraform, you can create a blueprint for your infrastructure that can be version-controlled, shared, and easily modified.

### Features

1. Declarative language: Terraform uses HCL, a declarative language that focuses on describing the desired end-state of your infrastructure. This makes it easy to understand and maintain, even for those new to IaC.
2. Modularity: Terraform encourages the use of modules, which are reusable building blocks for your infrastructure. This allows you to create and share reusable templates, improving collaboration and reducing duplicate code.
3. Plan & apply: Terraform's two-step process involves first generating an execution plan, which shows you the changes that will be made to your infrastructure, and then applying those changes if the plan is approved. This provides better visibility and control over your infrastructure changes.
4. State management: Terraform maintains a state file that tracks the current state of your infrastructure. This enables Terraform to detect changes, track dependencies, and ensure consistency between your infrastructure definition and actual deployed resources.
5. Providers: Providers in Terraform are plugins that enable communication with specific cloud platforms, services, or APIs. They define the resources, data sources, and input variables needed to manage infrastructure on a particular platform.

Terraform supports a wide range of cloud providers, including major players like AWS, Google Cloud Platform, and Azure, as well as smaller providers and on-premises solutions. The list of providers is on the [Terraform Registry](https://registry.terraform.io/browse/providers).

To better understand how and why Terraform is used, let’s dive into the Terraform Workflow.

### Terraform Workflow

1. Write the configuration: Define the desired infrastructure configuration in a Terraform file using a declarative language like HCL. This file specifies the resources you want to create, modify, or delete, along with their configuration settings.
2. Initialize the backend: Run **`terraform init`** to initialize Terraform in your working directory, download necessary provider plugins, and set up the backend for storing your Terraform state. This step only needs to be performed once per Terraform project.
3. Plan and apply changes: Run **`terraform plan`** to preview the actions that Terraform will take based on the defined configuration. This step generates an execution plan, showing you what actions Terraform will perform on your infrastructure to reach the desired state. Review the plan and if everything looks correct, run **`terraform apply`** to create or modify the infrastructure. Terraform will prompt you to confirm before executing the necessary API calls.
4. Destroy resources: If the resources are no longer needed, run **`terraform destroy`** to remove them. Terraform will prompt you to confirm before deleting the resources, ensuring that you don't accidentally remove something you still need.

Let’s implement this workflow with a real use case. 

## Creating a Single EC2 Instance on AWS with Terraform

AWS EC2 (Amazon Web Services Elastic Compute Cloud) is a scalable cloud computing service that provides virtual server instances for running applications and workloads. An EC2 instance has variety of purposes, including:

- Hosting web applications and websites.
- Running databases and data processing tasks.
- Deploying and managing containerized applications.
- Executing high-performance computing workloads.
- Serving as a development and test environment.

Upon creation, the EC2 instance starts running in the specified virtual private cloud (VPC), and you'll be billed for the resources used according to AWS pricing. Let’s go ahead and use terraform to create an EC2 instance on AWS. 

### Pre-requisites

- AWS Account: Sign up for an AWS account if you don't have one already.
- AWS CLI: Install and configure the AWS CLI on your local machine. For instructions, follow this guide: **[https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)**
- Terraform: Install Terraform by following the official installation guide: **[https://learn.hashicorp.com/tutorials/terraform/install-cli](https://learn.hashicorp.com/tutorials/terraform/install-cli)**
- Code editor (preferably VS Code)

The complete code is on Github.

### Setting up

Create a new directory for the Terraform project and navigate to it in your terminal.

```bash
mkdir terraform-ec2-instance
cd terraform-ec2-instance
```

Next, Create a file named `provider.tf` **i**n your working directory and add the following configuration to the **`provider.tf`** file to specify the AWS provider and the desired AWS region. 

```bash
provider "aws" {
  region = "us-east-1"
}
```

You can find AWS regions far right of the top navbar.

![Screen](https://res.cloudinary.com/sammy365/image/upload/v1681255779/Screenshot_2023-04-11_at_22.44.02_dlozii.png)

### Writing the configuration

To launch an instance in AWS, you need an Amazon Machine Image (AMI). It is a supported and maintained image provided by AWS that provides the information required to launch an instance

Create a file named **`ec2_instance.tf`** in your working directory and add the following configuration to the **`ec2_instance.tf`** file to define an EC2 instance resource. 

```bash
resource "aws_instance" "example" {
  ami           = "ami-092401efdf89a2db7"
  instance_type = "t2.micro"

  tags = {
    Name = "new-test-instance"
  }
}
```

Replace `ami-0c55b159cbfafe1f0` with an Amazon Machine Image (AMI) ID for your desired Linux distribution and instance region.

You can find an Amazon Linux 2 AMI ID from the EC2 dashboard [here](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/finding-an-ami.html#finding-an-ami-console). 

I chose this AMI because it’s not on the aws-marketplace so i don’t have to subscribe to use it. Your AMI list might vary based on the region you’re using.

![Screen](https://res.cloudinary.com/sammy365/image/upload/v1681255779/Screenshot_2023-04-12_at_00.03.01_aj5lyb.png)

You will want to make sure that the Root device type is EBS (Elastic Block Store) and Virtualization type is hvm (Hardware Virtual Machine). EBS is a persistent block storage service designed for use with Amazon EC2 instances and HVM is a type of virtualization mode available for EC2 instances.

The `t2.micro` instance is in the general purpose family with 1 vCPUs, 1.0 GiB of memory and low to moderate network performance. In our case, this is perfect because we are not doing any network or memory intensive work. 
Navigate to your **Instance** in your dashboard to see the list of available instance types.

Also, ensure your IAM user has `AmazonEC2FullAccess` permission allowed. 

### Initialize and apply the Terraform configuration

Run **`terraform init`** in your terminal to initialize your Terraform working directory.

```bash
terraform init
```

Then run **`terraform validate`** to validate your configuration files for any syntax errors.

```bash
terraform validate
```

Next, run **`terraform apply`** to create the EC2 instance. Terraform will prompt you to confirm that you want to perform the action. Type **`yes`** and press Enter to continue.

```bash
terraform apply
```

If everything works fine, you should see something like this on your terminal

![Screen](https://res.cloudinary.com/sammy365/image/upload/v1681255779/Screenshot_2023-04-12_at_00.00.51_r6hb5y.png)

### Verifying the EC2 instance

Head to your AWS Management Console and navigate to the EC2 Dashboard. You should see something like this:

![Screen](https://res.cloudinary.com/sammy365/image/upload/v1681255780/Screenshot_2023-04-12_at_00.12.41_ehg0ym.png)

Click on Instances running and you should see the instance we just created.

![Screen](https://res.cloudinary.com/sammy365/image/upload/v1681255779/Screenshot_2023-04-12_at_00.12.12_qpdqpa.png)

Notice how the configuration matches with the `ec2_instance.tf`.

### Clean up

Now we have achieved our goal, let’s destroy the EC2 instance to avoid unnecessary costs.

Run **`terraform destroy`** in your terminal. Terraform will prompt you to confirm that you want to perform the action. Type **`yes`** and press Enter to continue.

```bash
terraform destroy
```

After a few minutes, Terraform will destroy the EC2 instance. Ensure you check your dashboard to confirm.

## Limitations of Terraform

1. Learning curve: Users may face a learning curve when getting started with Terraform, particularly if they are new to Infrastructure as Code and cloud concepts.
2. Provider limitations: While Terraform supports many cloud providers, certain features or services might not be available or fully supported due to limitations in the provider implementation.
3. State management: Terraform relies on a state file to track the resources it manages. This state file can become a point of contention in team environments, requiring additional configuration and tooling, such as remote state backends and locking mechanisms.
4. Error messages: Terraform can sometimes produce verbose or unclear error messages, making it challenging to diagnose and fix issues.
5. Performance: Large infrastructure projects with numerous resources and modules can lead to slow performance during planning and applying changes.
6. No built-in rollback: Terraform does not have a built-in rollback mechanism for reverting changes, which can make recovering from errors more difficult. Users must plan their rollback strategy by leveraging backups, snapshots, or version control systems.

## So far this is what i know on IaC and Terraform…

IaC (Infrastructure as Code) is a key DevOps principle that streamlines infrastructure management and provisioning. It increases efficiency, collaboration, and automation by treating infrastructure as code. IaC offers several benefits, including automation, version control, consistency, scalability, and cost savings.

Terraform, an open-source IaC tool, enables defining, managing, and provisioning cloud infrastructure using HCL (HashiCorp Configuration Language). It provides modularity, a plan & apply approach, and state management, working with a wide range of cloud providers.

Terraform's workflow includes writing the configuration, initializing the backend, planning and applying changes, and destroying resources when needed. This simplifies infrastructure setup, encourages collaboration, and ensures consistency across environments.

## Resources

1. Terraform Documentation: Official documentation and getting started guide for Terraform.
**[https://www.terraform.io/docs/index.html](https://www.terraform.io/docs/index.html)**
2. AWS CloudFormation Documentation: Official documentation and getting started guide for AWS CloudFormation.
**[https://docs.aws.amazon.com/cloudformation/index.html](https://docs.aws.amazon.com/cloudformation/index.html)**
3. Gruntwork Blog - Terraform vs. CloudFormation: A comparison of the two IaC tools, discussing their strengths and weaknesses.
**[https://blog.gruntwork.io/terraform-vs-cloudformation-f3809ea9ac3a](https://blog.gruntwork.io/terraform-vs-cloudformation-f3809ea9ac3a)**
4. Medium - Terraform vs. AWS CloudFormation: A detailed comparison of Terraform and AWS CloudFormation, focusing on use cases and examples.
**[https://medium.com/@codeometry/terraform-vs-aws-cloudformation-1d9716122623](https://medium.com/@codeometry/terraform-vs-aws-cloudformation-1d9716122623)**
5. What is AWS CloudFormation.
[https://www.youtube.com/watch?v=0Sh9OySCyb4](https://www.youtube.com/watch?v=0Sh9OySCyb4)
6. ****AWS Cloudformation Step by Step Tutorial - Create a DynamoDB Table!****
[https://www.youtube.com/watch?v=YXVCdGyHDSk](https://www.youtube.com/watch?v=YXVCdGyHDSk)
7. ****Terraform Course - Automate your AWS cloud infrastructure.****
[https://www.youtube.com/watch?v=SLB_c_ayRMo](https://www.youtube.com/watch?v=SLB_c_ayRMo)
8. ****Terraform explained in 15 mins | Terraform Tutorial for Beginners.****
[https://www.youtube.com/watch?v=l5k1ai_GBDE](https://www.youtube.com/watch?v=l5k1ai_GBDE)
9. HashiCorp Learn - Introduction to Terraform: A comprehensive resource for learning Terraform, including tutorials, best practices, and use cases.
**[https://learn.hashicorp.com/terraform](https://learn.hashicorp.com/terraform)**
10. AWS CloudFormation Best Practices: Official best practices guide for using AWS CloudFormation.
**[https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/best-practices.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/best-practices.html)**