Reputation: 1140
First of all I am very new to AWS. Here is what i'm trying to achieve:
The public subnet is working perfectly well, I can access SSH and HTTP. The private subnet cause me a little trouble. For debug purpose i launched off an EC2 instance in it. From one of the "public instance" I am able to ping the "private instance" private IP (Well there is no public IP obviously)
Following the documentation, I created a VPC Endpoint in my private subnet which created a Network interface where i attached a security group that allow HTTP(S) (80 and 443) from the whole VPC CIDR. The endpoint type is Interface
So, now i have a private subnet with an Endpoint that allow HTTP(S) traffic. That endpoint have some (private) DNS NAME and (probably) also a private IP (Could not find it)
Now I want to add an API Gateway to front some AWS lambda. I create said API and as an Endpoint Type -> Private
Following this : Official Documentation The "only" way to "link" the API Gateway to the VPC Endpoint is to add a resource policy. So I input the following
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:<REGION>:<MY ID>:<API GATEWAY ID>/*/*/<MY RESOURCE>",
"Condition": {
"StringNotEquals": {
"aws:sourceVpce": "<VPC ENDPOINT ID>"
}
}
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:<REGION>:<MY ID>:<API GATEWAY ID>/*/*/<MY RESOURCE>"
}
]
}
And for the sake of completeness here is my lambda (python3.6):
from __future__ import division
def lambda_handler(event, context):
return {
"statusCode":200,
"headers": {"Content-Type": "application/json" },
"body" : "It work!"
}
Finally the problem:
What would be the URL to invoke this REST Api! API Gateway (In the lamdba Console) Tell me this:
https://<API GATEWAY ID>.<REGION>.amazonaws.com/<MY STAGE>/<MY RESOURCE>
Ok! Lets call that url: APIURL I ssh to the EC2 instance in the public subnet and run the following:
curl https://$APIURL
And it work: It output: "It work!" but that APIURL does not seem to come from the VPC endpoint so I try the following (still from the public subnet EC2):
curl https://vpce-XXXXXXX-XXXX.execute-api.REGION.vpce.amazonaws.com/<MY STAGE>/<MY RESOURCE>
And i get: {"message":"Forbidden"}
That does not seem right. As i test i change de API Gateway resource policy for the following:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:<REGION>:<MY ID>:<API ID>/*/*/<MY RESOURCE>"
}
]
}
And NOTHING changed. The APIURL is still working and the VPCE Url still give me forbidden.
What am I doing wrong? My apologies for the long post.
Upvotes: 9
Views: 5586
Reputation: 1481
A policy role update does not take effect until the api has been deployed to a stage.
If you update the resource policy after the API is created, you'll need to deploy the API to propagate the changes after you've attached the updated policy.
Upvotes: 7
Reputation: 1425
As your API url is working fine,there seems to be a problem with the policy.
In IAM policy Deny permission will override the Allow permission. Try changing your policy to the following:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": [
"arn:aws:execute-api:region:account-id:api-id/*",
"Condition": {
"StringEquals":{
"aws:SourceVpce": "<VPC Endpoint ID>"
}
}
]
},
{
"Effect": "Deny",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": [
"arn:aws:execute-api:region:account-id:api-id/*"
],
"Condition" : {
"StringNotEquals": {
"aws:SourceVpce": "<VPC Endpoint ID>"
}
}
}
]
}
For further reference, follow this link:
https://aws.amazon.com/blogs/compute/introducing-amazon-api-gateway-private-endpoints/
Upvotes: 0