IaC Bazaar
LinodeStatic-verified

Linode Cloud Firewall Baseline

Opinionated stateful firewall with deny-by-default inbound, curated allow rules, and multi-device attachment.

terraformAlt & Specialty Clouds#linode
linode-firewallterraform v1.7

Verification

Static-verified

Passed: validated and lint-clean (provider-schema-validated for AWS/Azure/GCP; Terraform-language lint elsewhere).

Conformance

  • Static validation (fmt · validate · tflint)
  • Security scan: findings disclosed (Checkov)
  • Plan tests (mocked: validation rules · outputs)

Provenance

  • SHA-256 checksum
  • Signature (pending)

Functional

  • Live test pending (no cloud run yet)

Last verified 2026-06-28 · how we verify

Documentation

linode-firewall

Opinionated stateful Linode Cloud Firewall: deny-by-default inbound, curated named allow-rule presets, and multi-device attachment. Works with Terraform and OpenTofu (>= 1.6), Linode provider >= 3.14, < 4.0.

Secure defaults:

  • inbound_policy = "DROP" — nothing is reachable unless you allow it
  • 23 curated presets (ssh, https, postgres, redis, k8s-api, wireguard, ping, ...) with the right protocol/ports baked in
  • Every rule — preset or custom — must declare explicit source CIDRs; there is no silent 0.0.0.0/0 default
  • Attachment via linode_firewall_device, so instances and NodeBalancers can be added or removed without touching rule definitions

Usage

module "firewall" {
  source = "./linode-firewall"

  label = "prod-web-fw"

  inbound_presets = {
    ssh   = { ipv4 = ["203.0.113.0/24"] }            # office only
    https = { ipv4 = ["0.0.0.0/0"], ipv6 = ["::/0"] } # public
  }

  custom_inbound_rules = [
    { label = "allow-app", protocol = "TCP", ports = "8000-8100", ipv4 = ["10.0.0.0/8"] },
  ]

  linode_ids = [12345678]
}

Inputs

NameTypeDefaultDescription
labelstringFirewall label, 3-32 chars (required)
inbound_policystring"DROP"Default inbound action (ACCEPT/DROP)
outbound_policystring"ACCEPT"Default outbound action
inbound_presetsmap(object){}Preset name => { ipv4 = [...], ipv6 = [...] } source CIDRs
custom_inbound_ruleslist(object)[]Free-form rules: label, action, protocol, ports, ipv4, ipv6
outbound_ruleslist(object)[]Outbound rules (needed only when outbound_policy = "DROP")
linode_idslist(number)[]Instance IDs to attach
nodebalancer_idslist(number)[]NodeBalancer IDs to attach
disabledboolfalseAdministratively disable the firewall
tagslist(string)[]Tags applied to the firewall

Preset names: ssh, http, https, http-alt, dns-tcp, dns-udp, smtp-submission, smtps, imaps, mysql, postgres, redis, mongodb, rdp, k8s-api, kubelet, node-exporter, prometheus, grafana, ntp, wireguard, openvpn, ping.

Outputs

NameDescription
firewall_idFirewall ID
firewall_labelFirewall label
firewall_statusFirewall status
linode_device_idsInstance ID => device ID map
nodebalancer_device_idsNodeBalancer ID => device ID map

Requirements

  • Terraform or OpenTofu >= 1.6
  • linode/linode provider >= 3.14, < 4.0
  • Cloud Firewall is a free Linode service.

Note: with the default inbound_policy = "DROP" and no presets, an attached instance accepts no inbound traffic at all — add at least an ssh preset scoped to your management CIDR before attaching.

Verification

Static-validated (fmt, validate, tflint). Live apply/destroy testing pending cloud sandbox availability — see catalog status.

License

Commercial — IaC Bazaar EULA. © IaC Bazaar. Original work (not derived from a third-party module).