I'm using AWS infrastructure (AWS API Gateway + Lambda) and I want to block the external access to my Development environment, I've created a policy using IAM to filter IPs Based on the Source IP:
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Deny",
"Action": "execute-api:Invoke",
"Resource": "*",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"192.168.0.1"
]
},
"Bool": {
"aws:ViaAWSService": "false"
}
}
}
}
What I'm trying to do now is to attach that policy to the lambdas that I'm deploying with serverless; I've tried this:
provider:
name: aws
runtime: nodejs12.x
resourcePolicy:
- arn:aws:iam::1234567890:policy/myCustomPolicy
But it's not working...
I know that some people, following the Serverless documentation, is directly creating and assigning the resource policy during the lambda deployment, but I don't want to do it in that way because I want to manage the policy from AWS (I don't want to re-deploy the Serverless every time that I've to change the policy).
Does anyone has a working example / recommendation about this?
After quite extensive internet research apparently there is no way to reference from the Gateway to an existing policy.
The main reason is that gateway policy is a resource policy not an IAM Policy more details here.
As an alternative solution, what I finally did is to extract that policy to a common file, my repository now looks as follow:
│
├── services
│ └── service-api
│ └── handler.js, serverless.yml
│
├── serverless-common.yml
└──.gitlab-ci.yml
In the serverless.yml file inside each service I'm referencing to a policy in the serverless-common.yml:
provider:
name: aws
runtime: nodejs12.x
apiGateway:
resourcePolicy: ${file(../../serverless.common.yml):custom.resourcePolicies.${opt:stage, 'none'}}
functions:
hello:
handler: handler.hello
events:
- http:
path: health
method: get
And in the serverless-common.yml
custom:
resourcePolicies:
dev:
- Effect: Allow
Principal: "*"
Action: execute-api:Invoke
Resource:
- execute-api:/*/*/*
Condition:
IpAddress:
aws:SourceIp:
- "176.25.129.133" # Whitelisted IP
pro:
- Effect: Allow
Principal: "*"
Action: execute-api:Invoke
Resource:
- execute-api:/*/*/*
This is the clearest solution I have been able to find, since the framework and AWS do not allow you to refer to an external policy, at least in this way you can have the whitelisted IP only in one place and refer to it from the serverless deployment.