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-vpcfor 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
| Name | Version |
|---|---|
| terraform | >= 1.9 |
| digitalocean | ~> 2.40 |
Providers
| Name | Version |
|---|---|
| digitalocean | ~> 2.40 |
Modules
No modules.
Resources
| Name | Type |
|---|---|
| digitalocean_loadbalancer.public | resource |
Inputs
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| cookie_ttl_seconds | The time-to-live (TTL) for the cookie in seconds. | number | null | no |
| disable_lets_encrypt_dns_records | Boolean controlling whether to disable the creation of DNS records for Let's Encrypt certificates. | bool | false | no |
| droplet_ids | A list of Droplet IDs to be assigned to the Load Balancer. | list(string) | null | no |
| droplet_tag | The tag of Droplets to be assigned to the Load Balancer. | string | null | no |
| enable_backend_keepalive | Boolean controlling whether to enable backend keepalive. | bool | false | no |
| enable_proxy_protocol | Boolean controlling whether to enable the PROXY protocol. | bool | false | no |
| firewall_allow | A list of firewall rules to allow. | list(any) | [] | no |
| firewall_deny | A 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
| Name | Description |
|---|---|
| loadbalancer_id | The ID of the DigitalOcean Load Balancer |
| loadbalancer_ip | The IP address of the DigitalOcean Load Balancer |
| loadbalancer_urn | The URN of the DigitalOcean Load Balancer |
Inputs
| Name | Description | Type | Default |
|---|---|---|---|
name | Name of the load balancer | string | n/a |
region | DigitalOcean region | string | n/a |
size | Size of the load balancer (e.g., lb-small, lb-medium) | string | "lb-small" |
type | Type of the load balancer (REGIONAL or GLOBAL) | string | "REGIONAL" |
network | Network type (EXTERNAL or INTERNAL) | string | "EXTERNAL" |
vpc_uuid | VPC ID for private networking | string | null |
firewall_allow | List of allowed IP ranges | list(object) | [] |
firewall_deny | List of denied IP ranges | list(object) | [] |
redirect_http_to_https | Redirect HTTP traffic to HTTPS | bool | false |
enable_proxy_protocol | Enable proxy protocol on the load balancer | bool | false |
enable_backend_keepalive | Enable keepalive between load balancer and backend | bool | false |
http_idle_timeout_seconds | HTTP idle timeout in seconds | number | 30 |
disable_lets_encrypt_dns_records | Disable automatic Let's Encrypt DNS records | bool | false |
forwarding_rules | Map of forwarding rules for traffic | map(object) | {} |
Outputs
| Name | Description |
|---|---|
loadbalancer_ip | Public IP address of the load balancer |
droplet_ids | List of droplet IDs assigned to the load balancer |
vpc_id | VPC 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.
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
- 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.
- 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.
- 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_rulesare configured with the correctentry_port,entry_protocol,target_port, andtarget_protocol. - Ensure that the target droplets are tagged correctly if using
droplet_tag, or that thedroplet_idsare accurate. - Check firewall settings to confirm that the load balancer is allowed to communicate with the droplets.
- Verify that the
SSL Certificate Not Applied
- Issue: The load balancer does not seem to be applying the specified SSL certificate.
- Solution:
- Ensure that the
certificate_namespecified in theforwarding_rulesmatches the actual certificate's name in DigitalOcean. - Confirm that the SSL certificate exists and is valid in the DigitalOcean control panel.
- Ensure that the
HTTP to HTTPS Redirection Not Working
- Issue: HTTP traffic is not automatically redirected to HTTPS.
- Solution:
- Check the
redirect_http_to_httpsvariable and ensure it is set totrue. - Verify that both HTTP and HTTPS forwarding rules are configured in
forwarding_rules.
- Check the
Firewall Rules Blocking Traffic
- Issue: Traffic is being blocked even though the load balancer is configured to allow it.
- Solution:
- Verify the
firewall_allowandfirewall_denysettings to ensure no conflicting rules exist. - Make sure that
firewall_denyrules do not inadvertently block IP ranges that should be allowed.
- Verify the
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
networkvariable is set toEXTERNALif the load balancer should be publicly accessible. - Confirm that firewall rules allow traffic from the public internet (e.g.,
0.0.0.0/0infirewall_allow).
- Ensure that the
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]