6.0.0 (2026-06-03)
Why the input shape changed
The AWS provider v6 retires aws_security_group_rule and the inline ingress / egress blocks in favor of one resource per rule (aws_vpc_security_group_ingress_rule and aws_vpc_security_group_egress_rule). On those resources every source attribute is singular: a rule has exactly one of cidr_ipv4, cidr_ipv6, prefix_list_id, or referenced_security_group_id. The provider no longer accepts the v5-style plural cidr_blocks/ipv6_cidr_blocks/prefix_list_ids lists on a single rule.
This change rules out v5's "implicit fan-out" patterns where a single module input expanded into N rules (e.g. ingress_cidr_blocks = ["10.0.0.0/16", "172.16.0.0/12"] + ingress_rules = ["postgresql-tcp"] produced two rules). v6 makes that fan-out explicit, and for the root module it removes preset names entirely:
- The root module is now a primitive — it accepts only structured
ingress_rules/egress_rules(map(object({ ... }))). Each map entry maps 1:1 to a v6 rule resource. There is no preset list, no source-companion variables. - The preset submodules (
modules/<service>/) are the sole mechanism for preset convenience. Each submodule wraps the root with one curated rule list and exposesingress_cidr_ipv4/ingress_cidr_ipv6/ingress_prefix_list_id/ingress_referenced_security_group_idasmap(string)inputs. Each entry produces one rule per preset rule, so a single submodule call still opens its preset to multiple sources without ambiguity.
If you previously mixed preset names with explicit rules in a single root-module call, the v6 path is to either call multiple preset submodules, or write the rules you want directly on the root module.
List of backwards incompatible changes
-
Terraform
v1.5.7is now minimum supported version -
AWS provider
v6.0.0is now minimum supported version (the module pins>= 6.29) -
The module has been rewritten on top of the AWS provider v6 resources
aws_security_group,aws_vpc_security_group_ingress_rule,aws_vpc_security_group_egress_rule,aws_vpc_security_group_rules_exclusive, andaws_vpc_security_group_vpc_association. The v5 use ofaws_security_group_ruleand inlineingress/egressblocks has been removed -
Rule inputs are now structured maps. The v5
ingress_rules/egress_ruleslists of named-rule strings, and theingress_with_*/egress_with_*/computed_ingress_with_*/computed_egress_with_*/number_of_computed_*families, have been replaced withingress_rules/egress_rulesofmap(object({ ... })) -
The root module no longer accepts preset names. Use a preset submodule under
modules/<service>/, or write structured rules directly viaingress_rules/egress_rules -
The implicit all-protocols egress rule (v5 default) has been removed. Pass
egress_rulesexplicitly to allow outbound traffic -
The implicit self-allow ingress rule (v5 default) has been removed. Add an explicit rule with
referenced_security_group_id = "self"to restore the behavior; the sentinel is rewritten to the security group's own id at apply time -
enable_exclusive_rulesistrueby default. Out-of-band rules added via the AWS console or other Terraform configurations will be reverted on the next apply. Set tofalseto opt out -
from_portandto_portare typed asnumber(werestringin v5). When only one offrom_port/to_portis supplied, the other now defaults to it via a symmetriccoalesce -
The security group no longer receives an implicit
Nametag set tovar.name. v5 merged{ Name = var.name }intotagsautomatically; v6 passesvar.tagsthrough unchanged. Settags = { Name = "..." }explicitly if you want to keep the prior behavior -
Submodules:
dax-clusterhas been renamed todynamodb-daxoracle-dbhas been renamed tooraclecarbon-relay-nghas been renamed tocarbon-relaykubernetes-api,smtp,smtps,smtp-submission,web, andzookeeperhave been removed- All preset rule keys drop the
-tcpsuffix when the service uses only one protocol (e.g.postgresql-tcp->postgresql); both-tcpand-udpsuffixes are kept where the service uses both - The four source inputs (
ingress_cidr_ipv4,ingress_cidr_ipv6,ingress_prefix_list_id,ingress_referenced_security_group_id) aremap(string)(were singularstringin earlier v6 drafts andlist(string)in v5). Each entry produces one ingress rule per preset rule; the four maps may be combined in a single call
Additional changes
Modified
- The root module now creates one
aws_vpc_security_group_ingress_rule/aws_vpc_security_group_egress_ruleper rule. Rule attachments live on a separate resource and are managed independently of the security group's lifecycle - Tags can be set per rule via the
tagsfield on each rule object. The per-ruleNametag defaults to the rule's map key aws_vpc_security_group_rules_exclusiveis created whenenable_exclusive_rules = true(the default). It enforces that the module owns the full set of rules on the security groupaws_vpc_security_group_vpc_associationallows associating the security group with additional VPCs (used by RAM-shared security groups). Provide viavpc_associations
Variable and output changes
-
Removed root-module variables:
ingress_cidr_blocksingress_ipv6_cidr_blocksingress_prefix_list_idsingress_with_cidr_blocksingress_with_ipv6_cidr_blocksingress_with_source_security_group_idingress_with_selfegress_cidr_blocksegress_ipv6_cidr_blocksegress_prefix_list_idsegress_with_cidr_blocksegress_with_ipv6_cidr_blocksegress_with_source_security_group_idegress_with_selfcomputed_ingress_cidr_blockscomputed_ingress_ipv6_cidr_blockscomputed_ingress_with_cidr_blockscomputed_ingress_with_ipv6_cidr_blockscomputed_ingress_with_source_security_group_idcomputed_ingress_with_selfcomputed_egress_cidr_blockscomputed_egress_ipv6_cidr_blockscomputed_egress_with_cidr_blockscomputed_egress_with_ipv6_cidr_blockscomputed_egress_with_source_security_group_idcomputed_egress_with_selfnumber_of_computed_*familyingress_cidr_ipv4,ingress_cidr_ipv6,ingress_prefix_list_id,ingress_referenced_security_group_id(root module — moved to the preset submodules)egress_cidr_ipv4,egress_cidr_ipv6,egress_prefix_list_id,egress_referenced_security_group_id(root module)ingress_presets,egress_presets(preset names are no longer accepted on the root module)auto_ingress_rules/auto_ingress_with_self(preset submodules)auto_egress_rules/auto_egress_with_self(preset submodules)
-
Renamed root-module variables:
ingress_rules(waslist(string)of preset names) ->ingress_rules(map(object({ ... }))of structured rules)egress_rules(waslist(string)of preset names) ->egress_rules(map(object({ ... }))of structured rules)
-
Added root-module variables:
vpc_associationsenable_exclusive_rulesregiontimeouts
-
Submodule source inputs:
ingress_cidr_ipv4(map(string))ingress_cidr_ipv6(map(string))ingress_prefix_list_id(map(string))ingress_referenced_security_group_id(map(string); use value"self"to reference the security group created by the submodule)
-
Renamed outputs:
security_group_id->idsecurity_group_arn->arnsecurity_group_vpc_id->vpc_idsecurity_group_owner_id->owner_idsecurity_group_name->namesecurity_group_descriptionhas been removed - usedescriptionfrom the inputthis_security_group_*aliases have been removed
See docs/UPGRADE-6.0.md for further details