[Bug]: Cannot deploy (apply) `aws_api_gateway_rest_api` with `aws_api_gateway_rest_api_policy` at the same time

Author: mklosittamCreated Feb 14, 2023Updated Sep 18, 2026
Labelsbugservice/apigatewaystale

Terraform Core Version

1.3.8

AWS Provider Version

4.54.0

Affected Resource(s)

  • aws_iam_policy_document (data)
  • aws_iam_role (resource)
  • aws_api_gateway_rest_api (resource)
  • aws_api_gateway_rest_api_policy (resource)

Expected Behavior

I should be able to deploy (or apply) all of this successfully.

Actual Behavior

I get an error. Curiously, after apply fails the first time, if i run plan and apply again, it succeeds the second time. Also, if I apply the 3 resources one by one, it also succeeds. This makes me think that the resource dependency tree is not being resolved correctly, but I don't see what the problem is in the code.

Relevant Error/Panic Output Snippet

bash
aws_api_gateway_rest_api_policy.api_policy: Creating...
╷
│ Error: setting API Gateway REST API Policy BadRequestException: Invalid policy document. Please check the policy syntax and ensure that Principals are valid.
│ 
│   with aws_api_gateway_rest_api_policy.api_policy,
│   on main.tf line 60, in resource "aws_api_gateway_rest_api_policy" "api_policy":
│   60: resource "aws_api_gateway_rest_api_policy" "api_policy" {

Terraform Configuration Files

terraform
terraform {
  required_version = ">= 1.2"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

data "aws_caller_identity" "current" {}

data "aws_iam_policy_document" "api_access" {
  statement {
    effect = "Allow"
    actions = [
      "sts:AssumeRole"
    ]
    principals {
      type        = "AWS"
      identifiers = [
        "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root",
      ]
    }
  }
}

data "aws_iam_policy_document" "api_invocation_policy" {
  statement {
    effect = "Allow"
    actions = [
      "execute-api:Invoke",
    ]
    resources = [
      "arn:aws:execute-api:*:${data.aws_caller_identity.current.account_id}:${aws_api_gateway_rest_api.api_gateway.id}/*/*/*"
    ]
  }
}

resource "aws_iam_role" "api_gateway_access_role" {
  name               = "api-gateway-access-role"
  path               = "/"
  assume_role_policy = data.aws_iam_policy_document.api_access.json
  inline_policy {
    name   = "api-invocation-policy"
    policy = data.aws_iam_policy_document.api_invocation_policy.json
  }
}

# --- API Gateway Resources --- #
resource "aws_api_gateway_rest_api" "api_gateway" {
  name        = "api-gateway"
  description = "Proxy to handle requests"
  endpoint_configuration {
    types = ["EDGE"]
  }
}

resource "aws_api_gateway_rest_api_policy" "api_policy" {
  rest_api_id = aws_api_gateway_rest_api.api_gateway.id
  policy      = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "${aws_iam_role.api_gateway_access_role.arn}"
      },
      "Action": "execute-api:Invoke",
      "Resource": "execute-api:/*"
    }
  ]
}
EOF
}


# ${aws_iam_role.api_gateway_access_role.arn}


output "aws_api_gateway_rest_api-api_gateway-id" {
  value = aws_api_gateway_rest_api.api_gateway.id
}


output "aws_api_gateway_rest_api_api_gateway_arn" {
  value = aws_api_gateway_rest_api.api_gateway.arn
}


output "aws_iam_role_api_gateway_access_role_arn" {
  value = aws_iam_role.api_gateway_access_role.arn
}

Steps to Reproduce

  • paste the code above in a new main.tf file.
  • run terraform plan -out=.terraform.tfplan
  • run terraform apply .terraform.tfplan

NOTE: backend.tf and provider.tf files have been omitted, since they are very stub. Everything else in my deployment works, except for these 3 resources along with their data.

Debug Output

bash
$ terraform apply .terraform.tfplan
aws_api_gateway_rest_api.api_gateway: Creating...
aws_api_gateway_rest_api.api_gateway: Creation complete after 1s [id=j0pcpiqboh]
data.aws_iam_policy_document.api_invocation_policy: Reading...
data.aws_iam_policy_document.api_invocation_policy: Read complete after 0s [id=3227615025]
aws_iam_role.api_gateway_access_role: Creating...
aws_iam_role.api_gateway_access_role: Creation complete after 1s [id=api-gateway-access-role]
aws_api_gateway_rest_api_policy.api_policy: Creating...
╷
│ Error: setting API Gateway REST API Policy BadRequestException: Invalid policy document. Please check the policy syntax and ensure that Principals are valid.
│ 
│   with aws_api_gateway_rest_api_policy.api_policy,
│   on main.tf line 60, in resource "aws_api_gateway_rest_api_policy" "api_policy":
│   60: resource "aws_api_gateway_rest_api_policy" "api_policy" {
│ 
╵
Releasing state lock. This may take a few moments...
ERRO[0007] 1 error occurred:
	* exit status 1

Panic Output

No response

Important Factoids

Curiously, after apply fails the first time, if i run plan and apply again, it succeeds the second time. Also, if I apply the 3 resources one by one, it also succeeds. This makes me think that the resource dependency tree is not being resolved correctly, but I don't see what the problem is in the code.

I searched online, but the only thing that seems relevant, isn't really helping me: https://stackoverflow.com/questions/54780301/invalid-policy-document-please-check-the-policy-syntax-and-ensure-that-principa

References

No response

Would you like to implement a fix?

No

Source: hashicorp/terraform-provider-aws