---
title: API Gateway deployment without access log setting
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Datadog Security > Code Security > Infrastructure as Code (IaC)
  Security > IaC Security Rules > API Gateway deployment without access log
  setting
---

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

# API Gateway deployment without access log setting

{% 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-api-gateway-deployment-without-access-log-setting` 

**Provider:** AWS

**Platform:** Terraform

**Severity:** Medium

**Category:** Observability

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

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

### Description{% #description %}

API Gateway deployments should have `access_log_settings` defined for each connected API Gateway Stage to ensure proper logging of API requests and responses. Without these settings, as shown below, critical API activity may go unlogged, making it difficult to track access patterns, detect malicious requests, or troubleshoot operational issues:

```
resource "aws_api_gateway_stage" "example" {
  ...
  access_log_settings {
    destination_arn = "arn:aws:logs:region:account-id:log-group:log-group-name"
    format          = "format"
  }
}
```

Leaving this misconfiguration unaddressed can hinder security monitoring and auditing, potentially exposing the environment to undetected abuse or data exfiltration.

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

```terraform
resource "aws_api_gateway_deployment" "example5" {
  rest_api_id   = "some rest api id"
  stage_name = "some name"
  stage_description = "some description"

  tags {
    project = "ProjectName"
  }
}

resource "aws_api_gateway_stage" "example0" {
  deployment_id = aws_api_gateway_deployment.example5.id
  rest_api_id   = aws_api_gateway_rest_api.example.id
  stage_name    = "example"

  access_log_settings {
    destination_arn = "dest"
    format = "format"
  }
}
```

```terraform
# Documented false positive: this stage IS correctly configured with a
# matching deployment_id and access_log_settings, but still gets flagged
# when evaluated purely from plan-JSON on a fresh-create plan (no prior
# state).
#
# query.rego's deployment_matches handles both the HCL interpolation form
# ("${aws_api_gateway_deployment.<name>.id}", matched via the literal
# reference string) and the plan-JSON resolved form, where deployment_id is
# the deployment's own resolved "id" value (a no-op/refresh plan against
# already-applied state). On a fresh-create plan, deployment_id is computed
# from the not-yet-created deployment's "id" and is entirely absent from
# planned_values pre-apply (resource_changes[].change.after_unknown.deployment_id
# == true), so neither matcher can succeed and a correctly-configured stage
# gets flagged as if its deployment_id were never set. Fixing this for real
# requires the plan-JSON parser (pkg/parser/json/tfplan.go) to also read
# resource_changes[].change.after_unknown / configuration.expressions[].references,
# which it currently does not.
resource "aws_api_gateway_deployment" "fp_example5" {
  rest_api_id        = "some rest api id"
  stage_name         = "some name"
  stage_description  = "some description"

  tags {
    project = "ProjectName"
  }
}

resource "aws_api_gateway_stage" "fp_example0" {
  deployment_id = aws_api_gateway_deployment.fp_example5.id
  rest_api_id   = aws_api_gateway_rest_api.fp_example.id
  stage_name    = "example"

  access_log_settings {
    destination_arn = "dest"
    format = "format"
  }
}
```

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

```terraform
resource "aws_api_gateway_deployment" "examplee" {
  rest_api_id   = "some rest api id"
  stage_name = "some name"
  tags {
    project = "ProjectName"
  }
}

resource "aws_api_gateway_stage" "example00" {
  deployment_id = aws_api_gateway_deployment.example.id
  rest_api_id   = aws_api_gateway_rest_api.example.id
  stage_name    = "example"
}
```

```terraform
resource "aws_api_gateway_deployment" "example3" {
  rest_api_id   = "some rest api id"
  stage_name = "some name"
  tags {
    project = "ProjectName"
  }
}

resource "aws_api_gateway_stage" "example000" {
  deployment_id = aws_api_gateway_deployment.example3.id
  rest_api_id   = aws_api_gateway_rest_api.example.id
  stage_name    = "example"
}
```

```terraform
resource "aws_api_gateway_deployment" "example4" {
  rest_api_id   = "some rest api id"
  stage_name = "some name"
  tags {
    project = "ProjectName"
  }
}

resource "aws_api_gateway_stage" "example0000" {
  deployment_id = aws_api_gateway_deployment.example4.id
  rest_api_id   = aws_api_gateway_rest_api.example.id
  stage_name    = "example"

  access_log_settings {
    destination_arn = "dest"
    format = "format"
  }
}
```
