Creating Infrastructure Using Terraform: A Coding Guide

Managing IT infrastructure can be daunting, filled with complexities and potential pitfalls. However, with the advent of powerful DevOps tools and practices such as Infrastructure-as-Code (IaC), these challenges can be mitigated significantly. In this post, we'll explore the modern DevOps ecosystem, delve into Infrastructure-as-Code, and provide a hands-on guide to automating your IT infrastructure using Terraform.


The Modern DevOps Ecosystem

DevOps is a pivotal aspect of modern software development and IT operations, amalgamating development and operations to streamline processes and achieve higher efficiency. Here are some key components of the DevOps ecosystem:


Configuration Management

Configuration management involves maintaining systems, software, and environments in a consistent state. As microservices architecture becomes prevalent, managing configurations centrally is crucial. Tools like Ansible, Chef, and Puppet enable automated configuration and management.


Containers and Container Orchestrators

Containers encapsulate applications and their dependencies, ensuring consistency across environments. Popular container engines compliant with the Open Containers Initiative (OCI) ensure compatibility with orchestrators like Kubernetes and Nomad. Orchestration tools manage containerized applications, helping in scaling and maintaining application uptime.


Continuous Integration and Continuous Delivery

CI/CD pipelines automate the software delivery process, integrating code changes frequently and delivering them rapidly. Tools like Jenkins, Travis CI, and CircleCI facilitate these processes, ensuring efficient and reliable software delivery.


Understanding Infrastructure-as-Code (IaC)

Infrastructure-as-Code (IaC) is a paradigm that uses code to manage and provision IT infrastructure. This practice treats infrastructure configurations as code, enabling version control, collaboration, and automation. One popular tool for IaC is Terraform, known for its maturity and wide range of plugins for various cloud providers.


Key Concepts of IaC

  • Versioning, Static Analysis, Review: IaC allows version control of infrastructure code, enabling tracking, analysis, and review, similar to application code.
  • Testing: IaC facilitates testing in pre-production environments, ensuring that infrastructure changes are safe and reliable.
  • Collaboration: Infrastructure as code promotes transparency and collaboration, leveraging practices like GitFlow for managing changes.
  • Separation of Concerns: IaC encourages modularization, making it possible to manage different components of the infrastructure independently.


Hands-On with Terraform: A Real-Life Scenario

Let’s dive into a practical example where we'll set up a hosting environment for a web application using Terraform. Our stack includes:


  • Virtual Private Server (VPS) from DigitalOcean
  • Content Delivery Network (CDN) and Domain Name System (DNS) services from Cloudflare
  • Email services from Mailgun


We'll walk through the setup of these components, assuming necessary dependencies are installed. Follow the Terraform installation guide if needed.


Configuring Providers

First, we define our providers in a provider.tf file:



provider "digitalocean" {
token = "DO_TOKEN_GOES_HERE"
}

provider "mailgun" {
api_key = "MAILGUN_API_KEY_GOES_HERE"
}

provider "cloudflare" {
email = "CLOUDFLARE_ACCOUNT_EMAIL"
token = "CLOUDFLARE_API_KEY"
}

Setting Up DigitalOcean Droplets

Next, we configure a virtual server (Droplet) in main.tf:



resource "digitalocean_droplet" "my_droplet" {
name = "my_droplet_name"
image = "debian-9-x64"
region = "ams3"
size = "s-1vcpu-1gb"
private_networking = true
monitoring = false
backups = false
resize_disk = true
}

Setting Up DNS and CDN with Cloudflare

We then configure DNS and CDN services in main.tf:



resource "cloudflare_zone" "my_domain_entry" {
zone = "example.com"
}

resource "cloudflare_zone_settings_override" "my_domain_entry_config" {
name = "${cloudflare_zone.my_domain_entry.zone}"
settings {
tls_1_3 = "on"
}
}

resource "cloudflare_record" "app_example_com_host" {
domain = "${cloudflare_zone.my_domain_entry.zone}"
type = "A"
name = "@"
value = "${digitalocean_droplet.my_droplet.ip_address}"
proxied = true
}

Configuring Mailgun for Email Services

Finally, we set up Mailgun for email services and link it with Cloudflare DNS:



resource "mailgun_domain" "example_mailing_domain" {
name = "m.example.com"
spam_action = "disabled"
smtp_password = "strong_password"
}

resource "cloudflare_record" "mail-receiving-dns-entry" {
count = 2
domain = "${cloudflare_zone.my_domain_entry.zone}"
type = "${lookup(mailgun_domain.example_mailing_domain.receiving_records[count.index], "record_type")}"
name = "${mailgun_domain.example_mailing_domain.name}."
value = "${lookup(mailgun_domain.example_mailing_domain.receiving_records[count.index], "value")}"
priority = "${lookup(mailgun_domain.example_mailing_domain.receiving_records[count.index], "priority")}"
}

resource "cloudflare_record" "mail-sending-dns-entry" {
count = 3
domain = "${cloudflare_zone.my_domain_entry.zone}"
type = "${lookup(mailgun_domain.example_mailing_domain.sending_records[count.index], "record_type")}"
name = "${lookup(mailgun_domain.example_mailing_domain.sending_records[count.index], "name")}."
value = "${lookup(mailgun_domain.example_mailing_domain.sending_records[count.index], "value")}"
}

Managing Infrastructure with Terraform Commands

Once the configurations are in place, we can manage the infrastructure using Terraform commands:


  • terraform init - Initializes the configuration, fetching plugins, and creating a local state file.
  • terraform plan - Compares the local state with the remote state and calculates the necessary changes.
  • terraform apply - Applies the changes to the cloud providers, provisioning the defined infrastructure.


Conclusion

Adopting Infrastructure-as-Code with Terraform empowers you to manage IT infrastructure efficiently and reliably. This approach is especially beneficial for complex systems with numerous services and resources. While we've used Terraform for our example, there are other robust tools available like Puppet, Chef, and SaltStack. Happy coding, and may your infrastructure be ever seamless!