Skip to content

ELB application load balancer deletion protection should be enabled

An Application Load Balancer often sits at the front of your entire application stack, routing traffic to dozens of target groups, handling TLS termination, and enforcing WAF rules. Accidental deletion causes immediate, total loss of inbound connectivity. Recovery means recreating the resource, re-registering targets, updating DNS records, and reattaching WAF ACLs. Under pressure, that process takes 30 minutes or more.

Deletion protection is a zero-cost, single-argument safeguard. It forces an explicit two-step process: disable protection, then delete. That gives teams time to catch mistakes in automation pipelines or manual console sessions before they become outages.

Retrofit consideration

Enabling deletion protection on existing ALBs causes no downtime or interruption. Any automation or teardown scripts that deliberately delete ALBs will fail until the flag is disabled first.

Implementation

Choose the approach that matches how you manage Terraform.

Use the compliance.tf module to enforce this control by default. See get started with compliance.tf.

module "alb" {
  source  = "hipaa.compliance.tf/terraform-aws-modules/alb/aws"
  version = ">=10.0.0,<11.0.0"

  access_logs = {
    bucket  = "example-bucket-abc123"
    enabled = true
  }
  internal = true
  listeners = {
    https = {
      certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
      forward = {
        target_group_key = "default"
      }
      protocol   = "HTTPS"
      ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
    }
  }
  load_balancer_type = "application"
  name               = "abc123"
  security_groups    = ["sg-abc12345"]
  subnets            = ["subnet-abc123", "subnet-def456"]
  target_groups = {
    default = {
      create_attachment = false
      name_prefix       = "def-"
      port              = 443
      protocol          = "HTTPS"
      target_type       = "ip"
    }
  }
  vpc_id = "vpc-12345678"
}

module "alb" {
  source  = "nist80053.compliance.tf/terraform-aws-modules/alb/aws"
  version = ">=10.0.0,<11.0.0"

  access_logs = {
    bucket  = "example-bucket-abc123"
    enabled = true
  }
  internal = true
  listeners = {
    https = {
      certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
      forward = {
        target_group_key = "default"
      }
      protocol   = "HTTPS"
      ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
    }
  }
  load_balancer_type = "application"
  name               = "abc123"
  security_groups    = ["sg-abc12345"]
  subnets            = ["subnet-abc123", "subnet-def456"]
  target_groups = {
    default = {
      create_attachment = false
      name_prefix       = "def-"
      port              = 443
      protocol          = "HTTPS"
      target_type       = "ip"
    }
  }
  vpc_id = "vpc-12345678"
}

module "alb" {
  source  = "nistcsf.compliance.tf/terraform-aws-modules/alb/aws"
  version = ">=10.0.0,<11.0.0"

  access_logs = {
    bucket  = "example-bucket-abc123"
    enabled = true
  }
  internal = true
  listeners = {
    https = {
      certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
      forward = {
        target_group_key = "default"
      }
      protocol   = "HTTPS"
      ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
    }
  }
  load_balancer_type = "application"
  name               = "abc123"
  security_groups    = ["sg-abc12345"]
  subnets            = ["subnet-abc123", "subnet-def456"]
  target_groups = {
    default = {
      create_attachment = false
      name_prefix       = "def-"
      port              = 443
      protocol          = "HTTPS"
      target_type       = "ip"
    }
  }
  vpc_id = "vpc-12345678"
}

module "alb" {
  source  = "fedrampmoderate.compliance.tf/terraform-aws-modules/alb/aws"
  version = ">=10.0.0,<11.0.0"

  access_logs = {
    bucket  = "example-bucket-abc123"
    enabled = true
  }
  internal = true
  listeners = {
    https = {
      certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
      forward = {
        target_group_key = "default"
      }
      protocol   = "HTTPS"
      ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
    }
  }
  load_balancer_type = "application"
  name               = "abc123"
  security_groups    = ["sg-abc12345"]
  subnets            = ["subnet-abc123", "subnet-def456"]
  target_groups = {
    default = {
      create_attachment = false
      name_prefix       = "def-"
      port              = 443
      protocol          = "HTTPS"
      target_type       = "ip"
    }
  }
  vpc_id = "vpc-12345678"
}

module "alb" {
  source  = "nist800171.compliance.tf/terraform-aws-modules/alb/aws"
  version = ">=10.0.0,<11.0.0"

  access_logs = {
    bucket  = "example-bucket-abc123"
    enabled = true
  }
  internal = true
  listeners = {
    https = {
      certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
      forward = {
        target_group_key = "default"
      }
      protocol   = "HTTPS"
      ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
    }
  }
  load_balancer_type = "application"
  name               = "abc123"
  security_groups    = ["sg-abc12345"]
  subnets            = ["subnet-abc123", "subnet-def456"]
  target_groups = {
    default = {
      create_attachment = false
      name_prefix       = "def-"
      port              = 443
      protocol          = "HTTPS"
      target_type       = "ip"
    }
  }
  vpc_id = "vpc-12345678"
}

module "alb" {
  source  = "cisacyberessentials.compliance.tf/terraform-aws-modules/alb/aws"
  version = ">=10.0.0,<11.0.0"

  access_logs = {
    bucket  = "example-bucket-abc123"
    enabled = true
  }
  internal = true
  listeners = {
    https = {
      certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
      forward = {
        target_group_key = "default"
      }
      protocol   = "HTTPS"
      ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
    }
  }
  load_balancer_type = "application"
  name               = "abc123"
  security_groups    = ["sg-abc12345"]
  subnets            = ["subnet-abc123", "subnet-def456"]
  target_groups = {
    default = {
      create_attachment = false
      name_prefix       = "def-"
      port              = 443
      protocol          = "HTTPS"
      target_type       = "ip"
    }
  }
  vpc_id = "vpc-12345678"
}

module "alb" {
  source  = "nydfs23.compliance.tf/terraform-aws-modules/alb/aws"
  version = ">=10.0.0,<11.0.0"

  access_logs = {
    bucket  = "example-bucket-abc123"
    enabled = true
  }
  internal = true
  listeners = {
    https = {
      certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
      forward = {
        target_group_key = "default"
      }
      protocol   = "HTTPS"
      ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
    }
  }
  load_balancer_type = "application"
  name               = "abc123"
  security_groups    = ["sg-abc12345"]
  subnets            = ["subnet-abc123", "subnet-def456"]
  target_groups = {
    default = {
      create_attachment = false
      name_prefix       = "def-"
      port              = 443
      protocol          = "HTTPS"
      target_type       = "ip"
    }
  }
  vpc_id = "vpc-12345678"
}

module "alb" {
  source  = "ffiec.compliance.tf/terraform-aws-modules/alb/aws"
  version = ">=10.0.0,<11.0.0"

  access_logs = {
    bucket  = "example-bucket-abc123"
    enabled = true
  }
  internal = true
  listeners = {
    https = {
      certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
      forward = {
        target_group_key = "default"
      }
      protocol   = "HTTPS"
      ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
    }
  }
  load_balancer_type = "application"
  name               = "abc123"
  security_groups    = ["sg-abc12345"]
  subnets            = ["subnet-abc123", "subnet-def456"]
  target_groups = {
    default = {
      create_attachment = false
      name_prefix       = "def-"
      port              = 443
      protocol          = "HTTPS"
      target_type       = "ip"
    }
  }
  vpc_id = "vpc-12345678"
}

module "alb" {
  source  = "cfrpart11.compliance.tf/terraform-aws-modules/alb/aws"
  version = ">=10.0.0,<11.0.0"

  access_logs = {
    bucket  = "example-bucket-abc123"
    enabled = true
  }
  internal = true
  listeners = {
    https = {
      certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
      forward = {
        target_group_key = "default"
      }
      protocol   = "HTTPS"
      ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
    }
  }
  load_balancer_type = "application"
  name               = "abc123"
  security_groups    = ["sg-abc12345"]
  subnets            = ["subnet-abc123", "subnet-def456"]
  target_groups = {
    default = {
      create_attachment = false
      name_prefix       = "def-"
      port              = 443
      protocol          = "HTTPS"
      target_type       = "ip"
    }
  }
  vpc_id = "vpc-12345678"
}

module "alb" {
  source  = "rbiitfnbfc.compliance.tf/terraform-aws-modules/alb/aws"
  version = ">=10.0.0,<11.0.0"

  access_logs = {
    bucket  = "example-bucket-abc123"
    enabled = true
  }
  internal = true
  listeners = {
    https = {
      certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
      forward = {
        target_group_key = "default"
      }
      protocol   = "HTTPS"
      ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
    }
  }
  load_balancer_type = "application"
  name               = "abc123"
  security_groups    = ["sg-abc12345"]
  subnets            = ["subnet-abc123", "subnet-def456"]
  target_groups = {
    default = {
      create_attachment = false
      name_prefix       = "def-"
      port              = 443
      protocol          = "HTTPS"
      target_type       = "ip"
    }
  }
  vpc_id = "vpc-12345678"
}

module "alb" {
  source  = "fedramplow.compliance.tf/terraform-aws-modules/alb/aws"
  version = ">=10.0.0,<11.0.0"

  access_logs = {
    bucket  = "example-bucket-abc123"
    enabled = true
  }
  internal = true
  listeners = {
    https = {
      certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
      forward = {
        target_group_key = "default"
      }
      protocol   = "HTTPS"
      ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
    }
  }
  load_balancer_type = "application"
  name               = "abc123"
  security_groups    = ["sg-abc12345"]
  subnets            = ["subnet-abc123", "subnet-def456"]
  target_groups = {
    default = {
      create_attachment = false
      name_prefix       = "def-"
      port              = 443
      protocol          = "HTTPS"
      target_type       = "ip"
    }
  }
  vpc_id = "vpc-12345678"
}

module "alb" {
  source  = "hipaasecurity2003.compliance.tf/terraform-aws-modules/alb/aws"
  version = ">=10.0.0,<11.0.0"

  access_logs = {
    bucket  = "example-bucket-abc123"
    enabled = true
  }
  internal = true
  listeners = {
    https = {
      certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
      forward = {
        target_group_key = "default"
      }
      protocol   = "HTTPS"
      ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
    }
  }
  load_balancer_type = "application"
  name               = "abc123"
  security_groups    = ["sg-abc12345"]
  subnets            = ["subnet-abc123", "subnet-def456"]
  target_groups = {
    default = {
      create_attachment = false
      name_prefix       = "def-"
      port              = 443
      protocol          = "HTTPS"
      target_type       = "ip"
    }
  }
  vpc_id = "vpc-12345678"
}

module "alb" {
  source  = "nistcsfv11.compliance.tf/terraform-aws-modules/alb/aws"
  version = ">=10.0.0,<11.0.0"

  access_logs = {
    bucket  = "example-bucket-abc123"
    enabled = true
  }
  internal = true
  listeners = {
    https = {
      certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
      forward = {
        target_group_key = "default"
      }
      protocol   = "HTTPS"
      ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
    }
  }
  load_balancer_type = "application"
  name               = "abc123"
  security_groups    = ["sg-abc12345"]
  subnets            = ["subnet-abc123", "subnet-def456"]
  target_groups = {
    default = {
      create_attachment = false
      name_prefix       = "def-"
      port              = 443
      protocol          = "HTTPS"
      target_type       = "ip"
    }
  }
  vpc_id = "vpc-12345678"
}

module "alb" {
  source  = "nist80053rev4.compliance.tf/terraform-aws-modules/alb/aws"
  version = ">=10.0.0,<11.0.0"

  access_logs = {
    bucket  = "example-bucket-abc123"
    enabled = true
  }
  internal = true
  listeners = {
    https = {
      certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
      forward = {
        target_group_key = "default"
      }
      protocol   = "HTTPS"
      ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
    }
  }
  load_balancer_type = "application"
  name               = "abc123"
  security_groups    = ["sg-abc12345"]
  subnets            = ["subnet-abc123", "subnet-def456"]
  target_groups = {
    default = {
      create_attachment = false
      name_prefix       = "def-"
      port              = 443
      protocol          = "HTTPS"
      target_type       = "ip"
    }
  }
  vpc_id = "vpc-12345678"
}

If you use terraform-aws-modules/alb/aws, set the right module inputs for this control. You can later migrate to the compliance.tf module with minimal changes because it is compatible by design.

module "alb" {
  source  = "terraform-aws-modules/alb/aws"
  version = ">=10.0.0,<11.0.0"

  access_logs = {
    bucket  = "example-bucket-abc123"
    enabled = true
  }
  internal = true
  listeners = {
    https = {
      certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
      forward = {
        target_group_key = "default"
      }
      protocol   = "HTTPS"
      ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
    }
  }
  load_balancer_type = "application"
  name               = "abc123"
  security_groups    = ["sg-abc12345"]
  subnets            = ["subnet-abc123", "subnet-def456"]
  target_groups = {
    default = {
      create_attachment = false
      name_prefix       = "def-"
      port              = 443
      protocol          = "HTTPS"
      target_type       = "ip"
    }
  }
  vpc_id = "vpc-12345678"

  enable_deletion_protection = true
}

Use AWS provider resources directly. See docs for the resources involved: aws_lb.

resource "aws_lb" "this" {
  access_logs {
    bucket = "pofix-logs-abc123"
  }
  internal = true
  name     = "pofix-abc123"
  subnets  = ["subnet-abc123", "subnet-def456"]

  enable_deletion_protection = true
}

What this control checks

The control validates that the aws_lb (or its alias aws_alb) resource has enable_deletion_protection set to true. By default this argument is false, so any ALB created without explicitly setting it will fail. The check applies only to load balancers where load_balancer_type is "application" (the default type). To pass, set enable_deletion_protection = true in every aws_lb resource block that creates an ALB. No additional resources or IAM permissions are required beyond the standard elasticloadbalancing:ModifyLoadBalancerAttributes action already needed to manage the ALB.

Common pitfalls

  • Default value is false

    Omit enable_deletion_protection and the ALB is created non-compliant. The argument defaults to false, so every aws_lb resource block needs an explicit enable_deletion_protection = true. There is no implicit inheritance from account-level settings or module defaults.

  • Terraform destroy blocked by deletion protection

    terraform destroy will fail on an ALB with deletion protection enabled, returning an OperationNotPermitted error. That's the intended behavior, but it catches teams off guard during automated teardowns of ephemeral environments. For non-production workspaces, use a variable to conditionally set the flag so teardown scripts don't require manual intervention.

  • Control scope excludes NLBs and GLBs

    This check targets only ALBs (load_balancer_type = "application"). Network Load Balancers and Gateway Load Balancers created through the same aws_lb resource type are not evaluated, even though they support the same enable_deletion_protection argument. If your threat model warrants it, cover them with a separate control.

  • Module abstractions may hide the argument

    Some community modules for ALBs default enable_deletion_protection to false or don't expose the variable at all. Before adopting a module like terraform-aws-modules/alb/aws, check the source. Don't assume the module sets this correctly; pin the variable explicitly if the module supports it.

Audit evidence

An auditor expects to see AWS Config rule evaluation results for the elb-deletion-protection-enabled managed rule showing all Application Load Balancers as COMPLIANT. Supporting evidence includes console screenshots of each ALB's attributes tab with 'Delete protection' set to 'Enabled', or CLI output from aws elbv2 describe-load-balancer-attributes --load-balancer-arn <arn> where deletion_protection.enabled returns "true".

For organizations running multiple accounts, a consolidated compliance report from Security Hub or a CSPM tool filtered to this check across all accounts and regions is the strongest evidence of continuous enforcement.

Framework-specific interpretation

HIPAA Omnibus Rule 2013: The HIPAA Security Rule's availability requirements under 45 CFR 164.312 apply to systems that route ePHI. An ALB in front of such systems is a critical availability control point, and accidental deletion directly interrupts access to that data. Deletion protection is one safeguard that supports those requirements.

NIST SP 800-53 Rev 5: SC-5 (Denial of Service Protection) and CM-3 (Configuration Change Control) are the primary mappings. An inadvertent ALB deletion is effectively a self-inflicted denial of service, and deletion protection enforces the deliberate two-step change process CM-3 calls for. CP-9 and CP-10 are also relevant since losing the ALB directly impacts recovery objectives.

NIST Cybersecurity Framework v2.0: The Protect function in CSF 2.0 covers both resilience and change control. Preventing accidental deletion of a load balancer fits within PR.IP (Information Protection Processes and Procedures), keeping infrastructure changes deliberate rather than recoverable-after-the-fact.

FedRAMP Moderate Baseline Rev 4: At the Moderate baseline, FedRAMP assessors treat internet-facing load balancers as critical infrastructure. CP-2, CM-3, and SC-5 all have a stake here: availability planning, change control, and denial-of-service protection respectively. An ALB without deletion protection is a gap examiners will note during assessment.

Tool mappings

Use these identifiers to cross-reference this control across tools, reports, and evidence.

  • Compliance.tf Control: elb_application_lb_deletion_protection_enabled

  • AWS Config Managed Rule: ELB_DELETION_PROTECTION_ENABLED

  • Checkov Check: CKV_AWS_150

  • Powerpipe Control: aws_compliance.control.elb_application_lb_deletion_protection_enabled

  • Prowler Check: elbv2_deletion_protection

  • AWS Security Hub Control: ELB.6

  • KICS Query: afecd1f1-6378-4f7e-bb3b-60c35801fdd4

Last reviewed: 2026-03-09