It is a best practice for AWS security groups to include a meaningful description attribute in their Terraform configuration, such as in the following example:
description = "Allow TLS inbound traffic"
Omitting the description field, as shown below, can lead to confusion and hinder effective management or auditing of security groups, especially in environments with many resources:
Without clear descriptions, security teams may struggle to quickly identify the purpose of a group, increasing the risk of misconfigurations and delayed incident response.
Compliant Code Examples
resource"aws_security_group""allow_tls"{name="allow_tls"description="Allow TLS inbound traffic"vpc_id=aws_vpc.main.idingress{description="TLS from VPC"from_port=443to_port=443protocol="tcp"cidr_blocks=[aws_vpc.main.cidr_block]ipv6_cidr_blocks=[aws_vpc.main.ipv6_cidr_block]}tags={Name="allow_tls"}}
resource"aws_security_group""allow_tls"{name="allow_tls"description="Managed by Terraform"vpc_id=aws_vpc.main.idingress{description="TLS from VPC"from_port=443to_port=443protocol="tcp"cidr_blocks=[aws_vpc.main.cidr_block]ipv6_cidr_blocks=[aws_vpc.main.ipv6_cidr_block]}tags={Name="allow_tls"}}
Non-Compliant Code Examples
# Note for positive2.json, the plan-JSON sibling exercising this same
# omitted-description scenario: see the plan-JSON variant DatadogPolicy
# body in query.rego for how it's resolved via
# configuration.root_module.resources[].expressions.
resource"aws_security_group""allow_tls"{name="allow_tls"vpc_id=aws_vpc.main.idingress{description="TLS from VPC"from_port=443to_port=443protocol="tcp"cidr_blocks=[aws_vpc.main.cidr_block]ipv6_cidr_blocks=[aws_vpc.main.ipv6_cidr_block]}tags={Name="allow_tls"}}
# A count-indexed security group with no description declared. See
# test/positive3.json for the plan-JSON equivalent: doc.resource.aws_security_group's
# flattened key is "allow_tls[0]" (index included), not the bare
# "allow_tls" that configuration.root_module.resources[].name would give -
# the plan-JSON DatadogPolicy body in query.rego resolves this by
# reading _dd_tfplan_meta.aws_security_group[name] instead, which is
# keyed identically to doc.resource.
resource"aws_vpc""main"{cidr_block="10.0.0.0/16"}resource"aws_security_group""allow_tls"{count=1name="allow-tls-${count.index}"vpc_id=aws_vpc.main.id}
# given:
# - a security group with description explicitly set to null
# when:
# - the AWS provider fills in its own schema default ("Managed by
# Terraform") since no real description was ever configured
# then:
# - still flag it, the same as if description had been omitted entirely
#
# description = null keeps a real entry under configuration_expressions
# (constant_value: null), not an absent key - a bare presence check alone
# would treat this as "a description was configured" and wrongly stay
# silent. See test/negative2.tf for the case that must correctly stay
# silent (description explicitly set to the non-null default string).
resource"aws_security_group""allow_tls"{name="allow_tls"description=nullvpc_id=aws_vpc.main.idingress{description="TLS from VPC"from_port=443to_port=443protocol="tcp"cidr_blocks=[aws_vpc.main.cidr_block]ipv6_cidr_blocks=[aws_vpc.main.ipv6_cidr_block]}tags={Name="allow_tls"}}
1
2
rulesets:- Terraform / AWS # Rules to enforce / AWS.
Request a personalized demo
Get Started with Datadog
Ask AI
AI-generated responses may be inaccurate. Verify important info.