Skip to main content

DigitalOcean Loadbalancer

https://github.com/terraform-arcus-modules/terraform-digitalocean-loadbalancer

Overview

The terraform-digitalocean-loadbalancer module provides a flexible, secure method to deploy and manage load balancers on DigitalOcean. The module is designed to handle advanced load balancing configurations such as custom forwarding rules, firewall settings, SSL termination, and traffic redirection, offering a secure and scalable solution for managing application traffic.

Key Features:

  • Flexible Traffic Management: Define forwarding rules for HTTP/HTTPS, configure multiple ports, and enable TLS termination with certificates.
  • Enhanced Security: Supports configurable firewall rules, IP allow/deny lists, and optional settings for proxy protocol and backend keepalive.
  • Integration with VPCs: Deploy load balancers within a VPC for secure private networking, protecting traffic from public exposure.
  • Custom SSL and Certificates: Easily configure SSL certificates for secure HTTPS traffic, with options for automatic DNS management.

Getting Started

Prerequisites

  • Terraform: Ensure you have Terraform v1.0+ installed.
  • DigitalOcean Account: A valid API token is required for authentication.
  • Dependencies: This module may depend on other Arcus modules, such as terraform-digitalocean-vpc for network isolation.

Quick Start Example

module "digitalocean_loadbalancer" {
source = "app.terraform.io/arcus/loadbalancer/digitalocean"
version = "0.0.2"

name = "my-loadbalancer"
region = "fra1"
size = "lb-medium"
type = "REGIONAL"
network = "EXTERNAL"
vpc_uuid = module.digitalocean_vpc.vpc_id

forwarding_rules = {
"http" = {
entry_port = 80
entry_protocol = "http"
target_port = 8080
target_protocol = "http"
}
"https" = {
entry_port = 443
entry_protocol = "https"
target_port = 443
target_protocol = "https"
certificate_name = "example.com"
}
}

firewall_allow = [
{
type = "cidr"
source = "0.0.0.0/0"
}
]
}

This example creates a public load balancer in the fra1 (Frankfurt) region, with basic forwarding rules for HTTP and HTTPS, and open access through a firewall rule.

Module Input and Output Variables

Requirements

NameVersion
terraform>= 1.9
digitalocean~> 2.40

Providers

NameVersion
digitalocean~> 2.40

Modules

No modules.

Resources

NameType
digitalocean_loadbalancer.publicresource

Inputs

NameDescriptionTypeDefaultRequired
cookie_ttl_secondsThe time-to-live (TTL) for the cookie in seconds.numbernullno
disable_lets_encrypt_dns_recordsBoolean controlling whether to disable the creation of DNS records for Let's Encrypt certificates.boolfalseno
droplet_idsA list of Droplet IDs to be assigned to the Load Balancer.list(string)nullno
droplet_tagThe tag of Droplets to be assigned to the Load Balancer.stringnullno
enable_backend_keepaliveBoolean controlling whether to enable backend keepalive.boolfalseno
enable_proxy_protocolBoolean controlling whether to enable the PROXY protocol.boolfalseno
firewall_allowA list of firewall rules to allow.list(any)[]no
firewall_denyA list of firewall rules to deny.list(any)[]no

| healthcheck_check_interval_seconds | The interval between health checks in seconds. | number | 10 | no | | healthcheck_path | The path to use for health checks. | string | "/" | no | | healthcheck_port | The port to use for health checks. | number | 8080 | no | | healthcheck_protocol | The protocol to use for health checks. | string | "http" | no | | healthy_threshold | The number of consecutive health check successes before considering a target healthy. | number | 5 | no | | http_idle_timeout_seconds | The idle timeout for HTTP connections in seconds. | number | 60 | no | | name | The name of the Load Balancer. | string | n/a | yes | | network | The network where the Load Balancer will be created. It must be either public or private. Defaults to public. | string | "EXTERNAL" | no | | project_id | The ID of the project where the Load Balancer will be created. | string | null | no | | redirect_http_to_https | Boolean controlling whether to redirect HTTP traffic to HTTPS. | bool | false | no | | region | The region where the Load Balancer will be created. | string | n/a | yes | | response_timeout_seconds | The timeout for health check responses in seconds. | number | 5 | no | | size | The size of the Load Balancer. It must be either lb-small, lb-medium, or lb-large. Defaults to lb-small. | string | "lb-small" | no | | size_unit | The unit of the size of the Load Balancer. It must be a number in the range 1 to 100. | string | null | no | | sticky_sessions_cookie_name | The name of the cookie to use for sticky sessions. | string | null | no | | sticky_sessions_type | The type of sticky sessions to use. It must be either none, cookies, or source_ip. Defaults to none. | string | "none" | no | | type | The type of the Load Balancer. It must be either fwd or glb. Defaults to fwd. | string | "REGIONAL" | no | | unhealthy_threshold | The number of consecutive health check failures before considering a target unhealthy. | number | 3 | no | | vpc_uuid | The ID of the VPC where the Load Balancer will be located. | string | null | no |

Outputs

NameDescription
loadbalancer_idThe ID of the DigitalOcean Load Balancer
loadbalancer_ipThe IP address of the DigitalOcean Load Balancer
loadbalancer_urnThe URN of the DigitalOcean Load Balancer

Inputs

NameDescriptionTypeDefault
nameName of the load balancerstringn/a
regionDigitalOcean regionstringn/a
sizeSize of the load balancer (e.g., lb-small, lb-medium)string"lb-small"
typeType of the load balancer (REGIONAL or GLOBAL)string"REGIONAL"
networkNetwork type (EXTERNAL or INTERNAL)string"EXTERNAL"
vpc_uuidVPC ID for private networkingstringnull
firewall_allowList of allowed IP rangeslist(object)[]
firewall_denyList of denied IP rangeslist(object)[]
redirect_http_to_httpsRedirect HTTP traffic to HTTPSboolfalse
enable_proxy_protocolEnable proxy protocol on the load balancerboolfalse
enable_backend_keepaliveEnable keepalive between load balancer and backendboolfalse
http_idle_timeout_secondsHTTP idle timeout in secondsnumber30
disable_lets_encrypt_dns_recordsDisable automatic Let's Encrypt DNS recordsboolfalse
forwarding_rulesMap of forwarding rules for trafficmap(object){}

Outputs

NameDescription
loadbalancer_ipPublic IP address of the load balancer
droplet_idsList of droplet IDs assigned to the load balancer
vpc_idVPC ID if the load balancer is in a VPC

Module Usage and Configuration Options

Load Balancer Configuration

The digitalocean_loadbalancer module provides a way to set up and manage DigitalOcean load balancers for your application environment. This configuration supports setting custom load balancer sizes, types, network settings, and forwarding rules, along with firewall rules for secure access control.

Example Usage:

Below is an example of how to configure a load balancer with various options, including HTTP and HTTPS forwarding rules, firewall rules, and custom network settings.

src/digitalocean_loadbalancer.tf
locals {
loadbalancers = {
"public" = {
size = "lb-medium"
type = "REGIONAL"
network = "EXTERNAL"
vpc_name = "datastore"
droplet_tag = "application:backend"
redirect_http_to_https = false
enable_proxy_protocol = false
enable_backend_keepalive = false
http_idle_timeout_seconds = 30
disable_lets_encrypt_dns_records = false
firewall_deny = [
{
type = "cidr"
source = "1.2.3.4/32"
},
{
type = "cidr"
source = "5.6.7.8/32"
}
]
firewall_allow = [
{
type = "cidr"
source = "0.0.0.0/0"
}
]
forwarding_rules = {
"http" = {
entry_port = 80
entry_protocol = "http"
target_port = 8080
target_protocol = "http"
certificate_name = null
tls_passthrough = null
}
"https" = {
entry_port = 443
entry_protocol = "https"
target_port = 443
target_protocol = "https"
certificate_name = "byteminds.io"
tls_passthrough = false
}
}
}
}
}

module "digitalocean_loadbalancer" {
for_each = local.loadbalancers

# Define the source of the load balancer module, which is managed through Terraform Cloud/Registry.
source = "app.terraform.io/arcus/loadbalancer/digitalocean"
version = "0.0.2"

# Set key attributes of the load balancer configuration.
name = join("-", [local.label.rendered, "lb", each.key])
region = local.context.values.region
size = each.value.size
type = each.value.type
network = each.value.network
vpc_uuid = module.digitalocean_vpc[each.value.vpc_name].vpc_id

# Optional attributes for droplet targeting and tagging
droplet_ids = try([for droplet_name in try(each.value.droplet_targets, false) :
module.digitalocean_droplet[droplet_name].droplet_id
], null)
droplet_tag = try(each.value.droplet_tag, null)

# Advanced configuration options
redirect_http_to_https = each.value.redirect_http_to_https
enable_proxy_protocol = each.value.enable_proxy_protocol
enable_backend_keepalive = each.value.enable_backend_keepalive
http_idle_timeout_seconds = each.value.http_idle_timeout_seconds
disable_lets_encrypt_dns_records = each.value.disable_lets_encrypt_dns_records

# Firewall configurations for IP-based access control
firewall_deny = [for rule in each.value.firewall_deny : format("%s:%s", rule.type, rule.source)]
firewall_allow = [for rule in each.value.firewall_allow : format("%s:%s", rule.type, rule.source)]

# Define HTTP and HTTPS forwarding rules with certificates
forwarding_rules = { for rule_key, rule in each.value.forwarding_rules : rule_key => {
entry_port = rule.entry_port
entry_protocol = rule.entry_protocol
target_port = rule.target_port
target_protocol = rule.target_protocol
certificate_name = rule.certificate_name != null ? module.digitalocean_certificate[rule.certificate_name].certificate_name : null
tls_passthrough = rule.tls_passthrough
} }

depends_on = [
module.digitalocean_certificate
]
}

Explanation of Configuration Options

  • Size and Type: Defines the load balancer size (lb-medium) and its operational type (REGIONAL).
  • Network and VPC: Configures the load balancer as an external (EXTERNAL) network load balancer within the datastore VPC.
  • Droplet Targets: Optionally targets specific droplets based on droplet_targets or the specified droplet_tag.
  • Firewall Rules:
    • firewall_deny: Lists CIDR blocks explicitly denied access.
    • firewall_allow: Configures CIDR blocks allowed access, such as 0.0.0.0/0 for open access.
  • Forwarding Rules:
    • Configures HTTP and HTTPS forwarding rules with specific ports and protocols.
    • Specifies the use of a certificate (byteminds.io) for HTTPS traffic.
    • Allows for TLS passthrough or termination options.

This configuration demonstrates how to set up a DigitalOcean load balancer with flexible forwarding, firewall rules, and droplet tagging, providing a secure, scalable solution for managing application traffic.

Module Architecture and Diagram

Architecture Overview

The terraform-digitalocean-application module is designed to deploy a secure, production-ready application infrastructure on DigitalOcean. It incorporates essential resources such as droplets, load balancers, VPCs, and other network components to create a flexible, highly available, and secure application environment.

The primary components and their interactions are as follows:

  • Load Balancer:
    • Acts as the main entry point for inbound traffic.
    • Balances traffic between multiple application instances (droplets).
    • Provides forwarding rules for HTTP and HTTPS traffic with optional redirection and TLS termination.
    • Enforces firewall rules to control access, ensuring that only specified IP ranges can reach the application.
    • Can optionally be configured with proxy protocol and backend keepalive settings to optimize performance.
  • Droplets:
    • Serve as the compute instances for running application services.
    • Automatically tagged and registered with the load balancer for efficient traffic distribution.
    • Can be scaled horizontally to handle increased traffic, based on load balancing configurations.
  • VPC (Virtual Private Cloud):
    • Isolates application resources within a private network.
    • Ensures secure internal communication between resources without exposing them to the public internet.
    • Allows for flexible network configurations such as subnets, firewall rules, and egress control for different environments (e.g., staging, production).
  • DNS and SSL Certificates:
    • Supports automatic DNS record management and SSL certificates through DigitalOcean, simplifying domain and SSL configuration for HTTPS traffic.
    • Certificates are used by the load balancer to provide secure connections.

Diagram

Below is a high-level architecture diagram illustrating how the terraform-digitalocean-application module organizes and connects these resources:

  • Droplets: Compute instances that process application traffic, tagged and managed automatically.
  • VPC: A private, secure network containing the application infrastructure.
  • DNS & SSL: Optional configuration for domain management and secure HTTPS traffic.

Detailed Component Interactions

  1. Traffic Flow:
  • Incoming traffic first reaches the load balancer, which routes it to the appropriate droplet instances based on defined forwarding rules.
  • HTTPS traffic is secured with an SSL certificate managed within DigitalOcean, ensuring encrypted communication from client to load balancer.
  1. Firewall Rules:
  • The load balancer firewall settings are configured with allow/deny rules that restrict access to specific IP ranges, adding an extra layer of security.
  1. Internal Communication:
  • Droplets communicate over the private VPC, ensuring data exchanges remain within a secure environment.
  • Only approved egress points are allowed to send data out of the VPC, which is especially useful for controlling data flows in highly regulated environments.

Security Considerations

  • TLS Termination: The load balancer performs TLS termination, managing SSL certificates for secure HTTPS connections and redirecting HTTP to HTTPS if configured.
  • Private Networking: By using a VPC, this module minimizes exposure to the public internet, allowing only controlled egress points.
  • Firewall Rules: Customizable allow/deny rules for IP ranges provide granular control over who can access application resources.

This architecture ensures a secure, scalable, and robust environment for deploying applications, meeting both internal and customer needs for a secure, compliant, and easy-to-manage infrastructure on DigitalOcean.

Troubleshooting and Common Issues

Load Balancer Not Routing Traffic as Expected

  • Issue: The load balancer is not routing traffic to droplets correctly.
  • Solution:
    • Verify that the forwarding_rules are configured with the correct entry_port, entry_protocol, target_port, and target_protocol.
    • Ensure that the target droplets are tagged correctly if using droplet_tag, or that the droplet_ids are accurate.
    • Check firewall settings to confirm that the load balancer is allowed to communicate with the droplets.

SSL Certificate Not Applied

  • Issue: The load balancer does not seem to be applying the specified SSL certificate.
  • Solution:
    • Ensure that the certificate_name specified in the forwarding_rules matches the actual certificate's name in DigitalOcean.
    • Confirm that the SSL certificate exists and is valid in the DigitalOcean control panel.

HTTP to HTTPS Redirection Not Working

  • Issue: HTTP traffic is not automatically redirected to HTTPS.
  • Solution:
    • Check the redirect_http_to_https variable and ensure it is set to true.
    • Verify that both HTTP and HTTPS forwarding rules are configured in forwarding_rules.

Firewall Rules Blocking Traffic

  • Issue: Traffic is being blocked even though the load balancer is configured to allow it.
  • Solution:
    • Verify the firewall_allow and firewall_deny settings to ensure no conflicting rules exist.
    • Make sure that firewall_deny rules do not inadvertently block IP ranges that should be allowed.

Load Balancer Failing to Provision

  • Issue: The load balancer fails to create or deploy.
  • Solution:
    • Check DigitalOcean's usage limits; you may have hit your limit on load balancer resources.
    • Verify that your API token has the necessary permissions to create load balancers in DigitalOcean.
    • Inspect the Terraform logs for any additional error messages related to the resource creation.

Load Balancer IP Not Accessible

  • Issue: The load balancer’s IP address is not accessible from the internet.
  • Solution:
    • Ensure that the network variable is set to EXTERNAL if the load balancer should be publicly accessible.
    • Confirm that firewall rules allow traffic from the public internet (e.g., 0.0.0.0/0 in firewall_allow).

Frequently Asked Questions (FAQ)

Q: Can I use this module to deploy an internal (private) load balancer?
A: Yes, by setting the network variable to INTERNAL, you can deploy a load balancer within a DigitalOcean VPC that is only accessible to resources within the private network.

Q: How do I configure the load balancer to handle SSL termination?
A: To enable SSL termination, add an HTTPS forwarding_rule and specify the certificate_name of the DigitalOcean-managed SSL certificate. This will handle SSL termination at the load balancer level.

Q: Can I restrict access to specific IP addresses?
A: Yes, use the firewall_allow and firewall_deny variables to control which IP ranges can access the load balancer. For example, you can allow only specific IPs by defining them in firewall_allow.

Q: Is it possible to redirect all HTTP traffic to HTTPS?
A: Yes, set the redirect_http_to_https variable to true, and ensure you have both HTTP and HTTPS forwarding rules configured in forwarding_rules.

Q: What happens if I exceed the load balancer limit on my DigitalOcean account?
A: DigitalOcean imposes limits on the number of load balancers per account. If you exceed this limit, you will need to either delete unused load balancers or contact DigitalOcean support to request a quota increase.

Q: Can I configure health checks on the load balancer?
A: Currently, the module does not directly expose health check configurations. However, the load balancer by default uses standard health checks. You can adjust your application's response to health checks to control load balancer behavior.

Q: How do I monitor load balancer traffic and performance?
A: DigitalOcean provides monitoring and alerting for load balancers in the control panel. You can view traffic metrics and set alerts for load balancer performance. Integrating with third-party monitoring tools may also be possible via DigitalOcean's API.

Q: Is autoscaling supported with this load balancer?
A: This module does not handle autoscaling directly. However, you can use it in combination with Terraform modules or scripts that add or remove droplets based on load. The load balancer will automatically distribute traffic to all tagged droplets or droplets specified by ID.

Changelog

v0.0.2

Release date: 2024-11-11

[Added] - Fixed
[Changed]
[Deprecated]
[Removed]
[Fixed]
[Security]