Search code examples
amazon-web-servicesterraformaws-api-gatewayterraform-provider-awsamazon-vpc

AWS API Gateway: deny traffic based on source IP addresses from managed prefix lists


Organisation provides me with a bunch of VPC managed prefix lists, representing VPN gateways and internal hosts from different regions.

These (and only these) IPs have to have access to a REST API gateway.

I currently list them in a resource policy like below, copying addresses to array manually.

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": "*",
                "Action": "execute-api:Invoke",
                "Resource": "arn:aws:execute-api:myapiarn/*",
                "Condition": {
                    "IpAddress": {
                        "aws:SourceIp": ["f.o.o/28", "b.a.r/24" ]
                    }
                }
            }
        ]
    }

Question is: can I reference managed prefix list directly from resource policy?

Are there alternative ways to achieve this? External tools, e.g. Terraform?


Solution

  • If I understood the question, then yes, it can be done using the api_gateway_rest_api_policy resource. To reference the prefix lists that exist outside of terraform, the data source for getting the prefix lists can be used. Based on the JSON snippet and using an example from the data source documentation, something like this could be used:

    data "aws_ec2_managed_prefix_list" "foo" {
      name = "foo-prefix-list"
    }
    
    data "aws_ec2_managed_prefix_list" "bar" {
      name = "bar-prefix-list"
    }
    

    Then, if you were to use the terraform resource, you would do the following

    data "aws_iam_policy_document" "api_gateway_resource_policy" {
      statement {
        effect = "Allow"
    
        principals {
          type        = "AWS"
          identifiers = ["*"]
        }
    
        actions   = ["execute-api:Invoke"]
        resources = ["arn:aws:execute-api:myapiarn/*"]
    
        condition {
          test     = "IpAddress"
          variable = "aws:SourceIp"
          values   = concat(data.aws_ec2_managed_prefix_list.foo.entries[*].cidr, data.aws_ec2_managed_prefix_list.bar.entries[*].cidr)
        }
      }
    }
    
    resource "aws_api_gateway_rest_api_policy" "api_gateway_resource_policy" {
      rest_api_id = aws_api_gateway_rest_api.your_api.id
      policy      = data.aws_iam_policy_document.api_gateway_resource_policy.json
    }