• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 9+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » Infrastructure as Code: Provisioning Secure Ruby Clusters on DigitalOcean Using Terraform

Infrastructure as Code: Provisioning Secure Ruby Clusters on DigitalOcean Using Terraform

Terraform Provider Configuration for DigitalOcean

To begin provisioning infrastructure on DigitalOcean using Terraform, we first need to configure the DigitalOcean provider. This involves specifying your API token and the region where your resources will be deployed. It’s crucial to manage your API token securely, ideally using environment variables rather than hardcoding it directly into your Terraform configuration files.

Create a file named main.tf and add the following configuration. Replace YOUR_DIGITALOCEAN_TOKEN with your actual DigitalOcean API token or, preferably, set the DIGITALOCEAN_TOKEN environment variable.

terraform {
  required_providers {
    digitalocean = {
      source  = "digitalocean/digitalocean"
      version = "~> 2.0"
    }
  }
}

provider "digitalocean" {
  token = var.do_token
  # Alternatively, if not using a variable:
  # token = "YOUR_DIGITALOCEAN_TOKEN"
}

variable "do_token" {
  description = "DigitalOcean API Token"
  type        = string
  sensitive   = true
}

variable "region" {
  description = "DigitalOcean region for resources"
  type        = string
  default     = "nyc3"
}

To use the environment variable method, you would export it in your shell:

export DIGITALOCEAN_TOKEN="YOUR_DIGITALOCEAN_TOKEN"

Then, when running Terraform commands, it will automatically pick up the token. If you are defining it via a variable, you can pass it during `terraform apply` or use a terraform.tfvars file (ensure this file is not committed to version control if it contains sensitive information).

Defining the Ruby Application Droplet

Next, we define the core infrastructure for our Ruby application. This typically involves a Droplet (a virtual private server) with a specific Linux distribution and size. For a production Ruby application, consider using a recent Ubuntu LTS version. We’ll also configure SSH access for deployment and management.

Add the following to your main.tf file:

resource "digitalocean_droplet" "ruby_app" {
  image    = "ubuntu-22-04-x64"
  name     = "ruby-app-01"
  region   = var.region
  size     = "s-2vcpu-4gb" # Adjust size based on your application's needs
  ssh_keys = [digitalocean_ssh_key.deployer.id]

  tags = [
    "ruby-app",
    "production",
    "terraform"
  ]

  # Enable monitoring for performance insights
  monitoring = true
}

resource "digitalocean_ssh_key" "deployer" {
  name       = "deployer-key"
  public_key = file("~/.ssh/id_rsa.pub") # Path to your local public SSH key
}

In this configuration:

  • image: Specifies the operating system image. ubuntu-22-04-x64 is a common choice for its stability and long-term support.
  • name: A descriptive name for the Droplet.
  • region: Uses the variable defined earlier.
  • size: Defines the Droplet’s resources. s-2vcpu-4gb is a mid-range option; scale up or down as needed.
  • ssh_keys: Links the Droplet to a specific SSH key for secure access. We define a new SSH key resource, digitalocean_ssh_key.deployer, which references your local public key. Ensure the path ~/.ssh/id_rsa.pub points to your actual public SSH key.
  • tags: Useful for organizing and filtering resources within DigitalOcean.
  • monitoring: Enables DigitalOcean’s built-in performance monitoring.

Securing the Droplet with a Firewall

Security is paramount. We’ll implement a DigitalOcean Cloud Firewall to control inbound and outbound traffic to our Ruby application Droplet. This provides a network-level security layer.

Add the following to your main.tf:

resource "digitalocean_firewall" "ruby_app_firewall" {
  name = "ruby-app-firewall"

  droplet_ids = [digitalocean_droplet.ruby_app.id]

  # Inbound rules
  inbound_rule {
    protocol         = "tcp"
    port_range       = "22" # SSH access
    source_addresses = ["0.0.0.0/0"] # Restrict this in production!
  }

  inbound_rule {
    protocol         = "tcp"
    port_range       = "80" # HTTP
    source_addresses = ["0.0.0.0/0"]
  }

  inbound_rule {
    protocol         = "tcp"
    port_range       = "443" # HTTPS
    source_addresses = ["0.0.0.0/0"]
  }

  # Outbound rules (default is allow all, explicit deny can be added if needed)
  outbound_rule {
    protocol              = "tcp"
    port_range            = "1-65535"
    destination_addresses = ["0.0.0.0/0"]
  }

  outbound_rule {
    protocol              = "udp"
    port_range            = "1-65535"
    destination_addresses = ["0.0.0.0/0"]
  }

  outbound_rule {
    protocol              = "icmp"
    destination_addresses = ["0.0.0.0/0"]
  }
}

Key aspects of the firewall configuration:

  • name: A descriptive name for the firewall.
  • droplet_ids: Associates this firewall with our previously defined Droplet.
  • inbound_rule: Defines allowed incoming traffic. We’ve opened SSH (port 22), HTTP (port 80), and HTTPS (port 443). Crucially, for production environments, you should restrict source_addresses for SSH to known IP ranges or bastion hosts, not 0.0.0.0/0.
  • outbound_rule: Defines allowed outgoing traffic. By default, DigitalOcean firewalls allow all outbound traffic. We’ve explicitly defined rules for TCP, UDP, and ICMP to cover common use cases.

Provisioning and Deployment Workflow

With the Terraform configuration in place, the provisioning process is straightforward. Ensure you have Terraform installed and your DigitalOcean API token is set up (either via environment variable or terraform.tfvars).

1. Initialize Terraform:

terraform init

This command downloads the DigitalOcean provider plugin and prepares your working directory.

2. Review the Execution Plan:

terraform plan -var="do_token=YOUR_DIGITALOCEAN_TOKEN"

If you are using environment variables for the token, you can omit the -var flag. This command shows you exactly what Terraform will create, modify, or destroy. Review this output carefully before proceeding.

3. Apply the Configuration:

terraform apply -var="do_token=YOUR_DIGITALOCEAN_TOKEN"

Again, omit the -var flag if using environment variables. Terraform will prompt you to confirm the changes. Type yes to proceed with provisioning the Droplet and firewall.

4. Accessing the Droplet:

After a successful apply, Terraform will output the IP address of your new Droplet. You can then SSH into it:

ssh root@<DROPLET_IP_ADDRESS>

You can retrieve the Droplet’s IP address from Terraform’s output or by querying the DigitalOcean API. To make the IP address easily accessible, you can add an output to your main.tf:

output "ruby_app_ip_address" {
  description = "The public IP address of the Ruby application Droplet."
  value       = digitalocean_droplet.ruby_app.ipv4_address
}

After adding this output, run terraform apply again. The IP address will then be displayed upon completion.

Next Steps: Application Deployment and Configuration Management

This Terraform setup provides a secure, provisioned Droplet. The next critical phase involves deploying your Ruby application and managing its configuration. Consider integrating tools like Ansible, Chef, or Capistrano for automated deployments. You might also want to set up a load balancer (e.g., DigitalOcean’s Load Balancer resource) if you plan to run multiple instances of your application for high availability and scalability.

For robust security, ensure you:

  • Restrict SSH access in the firewall to only necessary IP addresses.
  • Configure a non-root user on the Droplet for application deployment.
  • Implement HTTPS with SSL certificates (e.g., using Let’s Encrypt).
  • Regularly update your Droplet’s packages.

By leveraging Infrastructure as Code with Terraform, you establish a repeatable, version-controlled, and auditable process for managing your cloud infrastructure, significantly reducing manual errors and improving deployment speed.

Primary Sidebar

A little about the Author

Having 9+ Years of Experience in Software Development.
Expertised in Php Development, WordPress Custom Theme Development (From scratch using underscores or Genesis Framework or using any blank theme or Premium Theme), Custom Plugin Development. Hands on Experience on 3rd Party Php Extension like Chilkat, nSoftware.

Recent Posts

  • Step-by-Step: Diagnosing thread pools deadlock during concurrent ActiveRecord transaction processing on Linode Servers
  • Securing Your E-commerce APIs: Preventing SQL Injection (SQLi) in customized checkout queries in WooCommerce Implementations
  • Disaster Recovery 101: Architecting Auto-Failovers for MySQL and Ruby Deployments on Linode
  • High-Throughput Caching Strategies: Scaling MySQL for Perl Application APIs
  • Disaster Recovery 101: Architecting Auto-Failovers for DynamoDB and Laravel Deployments on DigitalOcean

Copyright © 2026 · Vinay Vengala