AWS Security Group Terraform module

June 3, 2026 ยท View on GitHub

Terraform module which creates EC2 security group within VPC on AWS.

SWUbanner

Usage

Root module

module "security_group" {
  source = "terraform-aws-modules/security-group/aws"

  name        = "example"
  description = "Example security group"
  vpc_id      = "vpc-12345678"

  ingress_rules = {
    https = {
      from_port   = 443
      ip_protocol = "tcp"
      cidr_ipv4   = "10.0.0.0/16"
      description = "HTTPS from internal"
    }
    self-all = {
      ip_protocol                  = "-1"
      referenced_security_group_id = "self"
      description                  = "All traffic from members of this SG"
    }
  }

  egress_rules = {
    all = {
      ip_protocol = "-1"
      cidr_ipv4   = "0.0.0.0/0"
    }
  }

  tags = {
    Environment = "dev"
  }
}

Preset submodule

Each preset submodule under modules/ ships a curated set of ingress rules for a specific service (PostgreSQL, Consul, Cassandra, etc.). Use one when a security group serves a single service.

module "postgresql_security_group" {
  source = "terraform-aws-modules/security-group/aws//modules/postgresql"

  name        = "postgresql"
  description = "PostgreSQL access"
  vpc_id      = "vpc-12345678"

  ingress_cidr_ipv4 = {
    vpc  = "10.0.0.0/16"
    peer = "172.16.0.0/12"
  }
}

Examples

  • Complete - Comprehensive example demonstrating the full module surface

Notes

Referencing the security group itself

To allow traffic between members of the security group created by this module, set referenced_security_group_id = "self" on the rule. The sentinel is rewritten to the security group's own id at apply time:

ingress_rules = {
  self-all = {
    ip_protocol                  = "-1"
    referenced_security_group_id = "self"
    description                  = "All traffic from members of this SG"
  }
}

use_name_prefix and the create-before-destroy lifecycle

The security group resource sets lifecycle { create_before_destroy = true } so replacements happen without dropping traffic. When use_name_prefix = false (i.e. you pin a static name), any change that forces replacement will fail because AWS cannot create a second security group with the same name in the same VPC. Either:

  • keep use_name_prefix = true (default), or
  • change name along with the replacement.

Requirements

NameVersion
terraform>= 1.5.7
aws>= 6.29

Providers

NameVersion
aws>= 6.29

Modules

No modules.

Resources

NameType
aws_security_group.thisresource
aws_vpc_security_group_egress_rule.thisresource
aws_vpc_security_group_ingress_rule.thisresource
aws_vpc_security_group_rules_exclusive.thisresource
aws_vpc_security_group_vpc_association.thisresource

Inputs

NameDescriptionTypeDefaultRequired
createControls if resources should be created (affects nearly all resources)booltrueno
descriptionDescription of security groupstringnullno
egress_rulesMap of egress rules to add to the security group
map(object({
name = optional(string)

cidr_ipv4 = optional(string)
cidr_ipv6 = optional(string)
description = optional(string)
from_port = optional(number)
ip_protocol = optional(string, "tcp")
prefix_list_id = optional(string)
referenced_security_group_id = optional(string)
tags = optional(map(string), {})
to_port = optional(number)
}))
{}no
enable_exclusive_rulesWhether to enforce that only the rules declared by this module exist on the security group. When true, out-of-band rules added via the AWS console or other Terraform configurations will be reverted on next applybooltrueno
ingress_rulesMap of ingress rules to add to the security group
map(object({
name = optional(string)

cidr_ipv4 = optional(string)
cidr_ipv6 = optional(string)
description = optional(string)
from_port = optional(number)
ip_protocol = optional(string, "tcp")
prefix_list_id = optional(string)
referenced_security_group_id = optional(string)
tags = optional(map(string), {})
to_port = optional(number)
}))
{}no
nameName of security groupstring""no
putin_khuyloDo you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo!booltrueno
regionRegion where the resource(s) will be managed. Defaults to the Region set in the provider configurationstringnullno
revoke_rules_on_deleteInstruct Terraform to revoke all of the Security Groups attached ingress and egress rules before deleting the rule itselfboolfalseno
tagsA map of tags to add to all resourcesmap(string){}no
timeoutsCreate and delete timeout configurations for the security group
object({
create = optional(string)
delete = optional(string)
})
nullno
use_name_prefixWhether to use the name (name) as a prefix, appending a random suffixbooltrueno
vpc_associationsMap of VPC IDs to associate the security group to
map(object({
vpc_id = string
}))
{}no
vpc_idID of the VPC where the security group is createdstringnullno

Outputs

NameDescription
arnThe ARN of the security group
idThe ID of the security group
nameThe name of the security group
owner_idThe owner ID
vpc_idThe VPC ID

Authors

Module is maintained by Anton Babenko with help from these awesome contributors.

License

Apache 2 Licensed. See LICENSE for full details.

Additional information for users from Russia and Belarus