---
title: SQS VPC endpoint without DNS resolution
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Datadog Security > Code Security > Infrastructure as Code (IaC)
  Security > IaC Security Rules > SQS VPC endpoint without DNS resolution
---

> For the complete documentation index, see [llms.txt](https://docs.datadoghq.com/llms.txt).

# SQS VPC endpoint without DNS resolution

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com, us2.ddog-gov.com

{% alert level="danger" %}
This product is not supported for your selected [Datadog site](https://docs.datadoghq.com/getting_started/site.md). ({% placeholder "user-datadog-site-name" /%}).
{% /alert %}

{% /callout %}

## Metadata{% #metadata %}

**Id:** `terraform-aws-sqs-vpc-endpoint-without-dns-resolution` 

**Provider:** AWS

**Platform:** Terraform

**Severity:** Low

**Category:** Networking and Firewall

#### Learn More{% #learn-more %}

- [Provider Reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc#enable_dns_support)

### Description{% #description %}

When configuring an Amazon SQS VPC Endpoint using Terraform, it is essential to have DNS resolution enabled for the associated VPC by setting `enable_dns_support = true`. If this is not set, such as in the configuration `enable_dns_support = false`, private DNS hostnames are not resolved within the VPC, causing communication failures for instances relying on DNS-based access to AWS services via the endpoint. This can result in application connectivity issues and may force the use of less secure public network routes, increasing the attack surface.

## Compliant Code Examples{% #compliant-code-examples %}

```terraform
resource "aws_vpc" "main2" {
  cidr_block = local.cidr_block
  enable_dns_support = true
  enable_dns_hostnames = false
}

resource "aws_vpc_endpoint" "sqs-vpc-endpoint2" {
  vpc_id            = aws_vpc.main2.id
  service_name      = "com.amazonaws.${local.region}.sqs"
  vpc_endpoint_type = "Interface"
  private_dns_enabled = true
  subnet_ids = [aws_subnet.public-subnet.id]
  security_group_ids = [aws_security_group.public-internet-sg.id]
}
```

```terraform
module "vpc" {
  source = "terraform-aws-modules/vpc/aws"
  version = "3.7.0"
  name = "my-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["eu-west-1a", "eu-west-1b", "eu-west-1c"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]

  enable_nat_gateway = true
  enable_vpn_gateway = true
  enable_dns_support = true

  tags = {
    Terraform = "true"
    Environment = "dev"
  }
}
```

```terraform
# Plan-JSON-only regression fixture (see test/negative3.json): a
# fresh-create SQS endpoint whose vpc_id references a newly created VPC
# with DNS support enabled (true). Documents the same shape as
# test/positive1.tf, but with enable_dns_support = true, to ensure the
# fresh-create fallback in query.rego does not fire when DNS support is
# actually enabled.
resource "aws_vpc" "main" {
  cidr_block           = "172.16.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true
}

resource "aws_vpc_endpoint" "sqs-vpc-endpoint" {
  vpc_id            = aws_vpc.main.id
  service_name      = "com.amazonaws.us-east-1.sqs"
  vpc_endpoint_type = "Interface"
}
```

## Non-Compliant Code Examples{% #non-compliant-code-examples %}

```terraform
# aws_vpc_endpoint.sqs-vpc-endpoint.vpc_id references aws_vpc.main.id, a
# newly created resource. On a real pre-apply plan the VPC's id is
# unknown, so vpc_id is omitted from planned_values (see
# test/negative3.json for the plan-JSON equivalent). The VPC's own
# enable_dns_support is still fully known, though (it's a direct user
# input, not provider-computed) - detected via the fresh-create fallback
# in query.rego, which derives the VPC's Terraform name from
# _dd_tfplan_meta's unresolved vpc_id reference instead of needing the
# resolved id itself.
locals {
  region = "us-east-1"
  cidr_block = "172.16.0.0/16"
  public_subnet_cidr_block = "172.16.100.0/24"
  quad_zero_cidr_block = "0.0.0.0/0"
}

provider "aws" {
  region = local.region
}

resource "aws_vpc" "main" {
  cidr_block = local.cidr_block
  enable_dns_support = false
  enable_dns_hostnames = false
}

resource "aws_subnet" "public-subnet" {
  vpc_id     = aws_vpc.main.id
  cidr_block = local.public_subnet_cidr_block

  tags = {
    Name = "public-subnet"
  }
}

resource "aws_route_table" "public-rtb" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = local.cidr_block
    vpc_endpoint_id = aws_vpc_endpoint.sqs-vpc-endpoint.id
  }

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw.id
  }

  tags = {
    Name = "public-rtb"
  }
}

resource "aws_route_table_association" "public-rtb-assoc" {
  subnet_id      = aws_subnet.public-subnet.id
  route_table_id = aws_route_table.public-rtb.id
}

resource "aws_security_group" "public-internet-sg" {
  name        = "public-internet-sg"
  description = "Allow all local traffic with internet access"
  vpc_id      = aws_vpc.main.id

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = [local.quad_zero_cidr_block]
  }

  ingress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = [local.cidr_block]
  }

}

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"] # Canonical
}

resource "aws_instance" "test-ec2-instance" {
  ami = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"
  subnet_id = aws_subnet.public-subnet.id
  vpc_security_group_ids = [aws_security_group.public-internet-sg.id]
}

resource "aws_vpc_endpoint" "sqs-vpc-endpoint" {
  vpc_id            = aws_vpc.main.id
  service_name      = "com.amazonaws.${local.region}.sqs"
  vpc_endpoint_type = "Interface"
  private_dns_enabled = true
  subnet_ids = [aws_subnet.public-subnet.id]
  security_group_ids = [aws_security_group.public-internet-sg.id]
}

resource "aws_sqs_queue" "test-queue" {
  name = "test-queue"
}

resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main.id
}
```

```terraform
resource "aws_vpc" "main3" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_support   = false
  enable_dns_hostnames = false
}

resource "aws_vpc_endpoint" "sqs-vpc-endpoint3" {
  vpc_id              = aws_vpc.main3.id
  service_name        = "com.amazonaws.us-east-1.sqs"
  vpc_endpoint_type   = "Interface"
  private_dns_enabled = true
}
```

```terraform
# Plan-JSON-only regression fixture (see test/positive4.json): both the VPC
# and the SQS endpoint live inside a child module. The endpoint's vpc_id
# reference ("aws_vpc.sqs_scope_test", module-relative) must be qualified
# with the child module's own scope before it can match the VPC's
# flattened resource key ("module.child.sqs_scope_test") - see
# query.rego's common_lib.reference_targets_resource-based fresh-create
# body. Resource names are deliberately distinct from every other fixture
# in this directory (not "main") to avoid a cross-fixture name collision:
# all positive*.tf/.json files are batched into the same test run, and
# vpcs_by_name/used_refs walk every loaded document, so reusing "main"
# here would let positive1.tf's own aws_vpc.main (also
# enable_dns_support = false) satisfy this fixture's lookup even without
# the module-scope fix, masking a real regression.
module "child" {
  source = "./child"
}
```
