-
Notifications
You must be signed in to change notification settings - Fork 937
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2013 from sabornibhattacharya/main
New pattern - APIGW Lambda with wildcard resource-based policy using CDK
- Loading branch information
Showing
15 changed files
with
375 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
*.swp | ||
package-lock.json | ||
__pycache__ | ||
.pytest_cache | ||
.venv | ||
*.egg-info | ||
|
||
# CDK asset staging directory | ||
.cdk.staging | ||
cdk.out |
103 changes: 103 additions & 0 deletions
103
apigw-lambda-wildcard-resourcebasedpolicy-cdk/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
# Amazon API Gateway to AWS Lambda with wildcard resource-based policy | ||
|
||
Create a REST API with proxy integration to a Lambda function to keep the size of resource-based policy within the allowed hard limit. Currently, in an API Gateway-Lambda setup whenever an user adds an integration, CDK adds a new policy to the Lambda function's resource-based policy. It might result in exceeding the policy size limit for Lambda function which is 20KB.", | ||
This sample project demonstrates how to use CDK to create a customized integration that would keep the policy size within limit by using wildcards in the resource-based policy. | ||
|
||
|
||
Learn more about this pattern at Serverless Land Patterns: [https://serverlessland.com/patterns/apigw-lambda-wildcard-resourcebasedpolicy-cdk](https://serverlessland.com/patterns/apigw-lambda-wildcard-resourcebasedpolicy-cdk) | ||
|
||
Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example. | ||
|
||
## Requirements | ||
|
||
* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources. | ||
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured | ||
* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) | ||
* [Node and NPM](https://nodejs.org/en/download/) installed | ||
* [Python, pip, virtuenv](https://docs.aws.amazon.com/cdk/latest/guide/work-with-cdk-python.html) installed | ||
* [AWS Cloud Development Kit](https://docs.aws.amazon.com/cdk/latest/guide/cli.html) (AWS CDK) installed | ||
|
||
## Deployment Instructions | ||
|
||
1. Clone the project to your local working directory | ||
|
||
```sh | ||
git clone https://github.com/aws-samples/serverless-patterns/ | ||
``` | ||
|
||
2. Change the working directory to this pattern's directory | ||
|
||
```sh | ||
cd serverless-patterns/apigw-lambda-wildcard-resourcebasedpolicy-cdk | ||
``` | ||
|
||
3. Create and activate the project's virtual environment. This allows the project's dependencies to be installed locally in the project folder, instead of globally. Note that if you have multiple versions of Python installed, where the `python` command references Python 2.x, then you can reference Python 3.x by using the `python3` command. You can check which version of Python is being referenced by running the command `python --version` or `python3 --version` | ||
|
||
```sh | ||
python -m venv .venv | ||
source .venv/bin/activate | ||
``` | ||
|
||
4. Install the project dependencies | ||
|
||
```sh | ||
python -m pip install -r requirements.txt | ||
``` | ||
|
||
5. Deploy the stack to your default AWS account and region. | ||
|
||
```sh | ||
cdk deploy | ||
``` | ||
|
||
## How it works | ||
|
||
The CDK app deploys the resources and the IAM permissions required to run the application. | ||
|
||
## Testing | ||
|
||
Log into the AWS Console, browse to Amazon API Gateway console to find REST API: | ||
|
||
1. Verify the Lambda function integrated to the API resources. | ||
|
||
2. Navigate to the function permissions option to validate its resource-based: | ||
```JSON | ||
{ | ||
"Version": "2012-10-17", | ||
"Id": "default", | ||
"Statement": [ | ||
{ | ||
"Sid": "CdkApigwLambdaWildCardPolicyStack-CDKFunction1BFFE2B32-wXxkAliuaQ0d", | ||
"Effect": "Allow", | ||
"Principal": { | ||
"Service": "apigateway.amazonaws.com" | ||
}, | ||
"Action": "lambda:InvokeFunction", | ||
"Resource": "arn:aws:lambda:us-east-1:01234567890:function:CdkApigwLambdaWildCardPolicySt-CDKFunction43C45D9B-pnj1nEvuxNCR", | ||
"Condition": { | ||
"ArnLike": { | ||
"AWS:SourceArn": "arn:aws:execute-api:us-east-1:01234567890:abcd1234/*/*/*" | ||
} | ||
} | ||
} | ||
] | ||
} | ||
``` | ||
|
||
3. Invoke your API endpoint to validate that your function is getting invoked successfully. Your API should return this response which is sent by your funtion | ||
``` | ||
Invoked Successfully | ||
``` | ||
|
||
## Cleanup | ||
|
||
Run the given command to delete the resources that were created. It might take some time for the CloudFormation stack to get deleted. | ||
|
||
```sh | ||
cdk destroy | ||
``` | ||
|
||
---- | ||
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
|
||
SPDX-License-Identifier: MIT-0 |
67 changes: 67 additions & 0 deletions
67
...ambda-wildcard-resourcebasedpolicy-cdk/apigw-lambda-wildcard-resourcebasedpolicy-cdk.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
{ | ||
"title": "Amazon API Gateway to AWS Lambda with wildcard resource-based policy", | ||
"description": "Create a REST API with proxy integration to a Lambda function to keep the size of resource-based policy within the allowed hard limit.", | ||
"language": "Python", | ||
"level": "200", | ||
"framework": "CDK", | ||
"introBox": { | ||
"headline": "How it works", | ||
"text": [ | ||
"Currently, in an API Gateway-Lambda setup whenever an user adds an integration, CDK adds a new policy to the Lambda function's resource-based policy.", | ||
"It might result in exceeding the policy size limit for Lambda function which is 20KB.", | ||
"This sample project demonstrates how to use CDK to create a customized integration that would keep the policy size within limit by using wildcards in the resource-based policy." | ||
] | ||
}, | ||
"gitHub": { | ||
"template": { | ||
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/apigw-lambda-wildcard-resourcebasedpolicy-cdk", | ||
"templateURL": "serverless-patterns/apigw-lambda-wildcard-resourcebasedpolicy-cdk", | ||
"projectFolder": "apigw-lambda-wildcard-resourcebasedpolicy-cdk", | ||
"templateFile": "template.yaml" | ||
} | ||
}, | ||
"resources": { | ||
"bullets": [] | ||
}, | ||
"deploy": { | ||
"text": [ | ||
"sam deploy" | ||
] | ||
}, | ||
"testing": { | ||
"text": [ | ||
"See the GitHub repo for detailed testing instructions." | ||
] | ||
}, | ||
"cleanup": { | ||
"text": [ | ||
"Delete the stack: sam delete." | ||
] | ||
}, | ||
"authors": [ | ||
{ | ||
"name": "Saborni Bhattacharya", | ||
"image": "https://drive.google.com/file/d/1AZFquOkafEQRUlrT4hKOtIbt4Cq66SHd/view?usp=sharing", | ||
"bio": "I am Saborni working as a Cloud Engineer at AWS SE Serverless.", | ||
"linkedin": "saborni-bhattacharya-5b523812a" | ||
} | ||
], | ||
"patternArch": { | ||
"icon1": { | ||
"x": 20, | ||
"y": 50, | ||
"service": "apigw", | ||
"label": "API Gateway REST API" | ||
}, | ||
"icon2": { | ||
"x": 80, | ||
"y": 50, | ||
"service": "lambda", | ||
"label": "AWS Lambda" | ||
}, | ||
"line1": { | ||
"from": "icon1", | ||
"to": "icon2" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import aws_cdk as cdk | ||
|
||
from cdk_apigw_lambda_wildcardpolicy_stack.cdk_apigw_lambda_wildcardpolicy_stack import CdkApigwLambdaWildCardPolicyStack | ||
|
||
app = cdk.App() | ||
|
||
# Instantiate the CDK stack | ||
CdkApigwLambdaWildCardPolicyStack(app, 'CdkApigwLambdaWildCardPolicyStack') | ||
|
||
# Synthesize the CloudFormation template | ||
app.synth() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
{ | ||
"app": "python3 app.py", | ||
"watch": { | ||
"include": [ | ||
"**" | ||
], | ||
"exclude": [ | ||
"README.md", | ||
"cdk*.json", | ||
"requirements*.txt", | ||
"source.bat", | ||
"**/__init__.py", | ||
"python/__pycache__", | ||
"tests" | ||
] | ||
}, | ||
"context": { | ||
"@aws-cdk/aws-lambda:recognizeLayerVersion": true, | ||
"@aws-cdk/core:checkSecretUsage": true, | ||
"@aws-cdk/core:target-partitions": [ | ||
"aws", | ||
"aws-cn" | ||
], | ||
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, | ||
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, | ||
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, | ||
"@aws-cdk/aws-iam:minimizePolicies": true, | ||
"@aws-cdk/core:validateSnapshotRemovalPolicy": true, | ||
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, | ||
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, | ||
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, | ||
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true, | ||
"@aws-cdk/core:enablePartitionLiterals": true, | ||
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, | ||
"@aws-cdk/aws-iam:standardizedServicePrincipals": true, | ||
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, | ||
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, | ||
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, | ||
"@aws-cdk/aws-route53-patters:useCertificate": true, | ||
"@aws-cdk/customresources:installLatestAwsSdkDefault": false, | ||
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, | ||
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, | ||
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, | ||
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, | ||
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, | ||
"@aws-cdk/aws-redshift:columnId": true, | ||
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, | ||
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, | ||
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, | ||
"@aws-cdk/aws-kms:aliasNameRef": true, | ||
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, | ||
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true, | ||
"@aws-cdk/aws-efs:denyAnonymousAccess": true, | ||
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, | ||
"@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, | ||
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true | ||
} | ||
} |
Empty file.
39 changes: 39 additions & 0 deletions
39
...policy-cdk/cdk_apigw_lambda_wildcardpolicy_stack/cdk_apigw_lambda_wildcardpolicy_stack.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
from constructs import Construct | ||
from aws_cdk import ( | ||
Stack, | ||
aws_apigateway as apigateway, | ||
aws_lambda as _lambda, | ||
aws_iam as iam | ||
) | ||
from aws_cdk.aws_lambda import CfnPermission | ||
|
||
class CdkApigwLambdaWildCardPolicyStack(Stack): | ||
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: | ||
super().__init__(scope, construct_id, **kwargs) | ||
|
||
# Create a Lambda function | ||
lambda_function = _lambda.Function(self, 'CDKFunction',runtime=_lambda.Runtime.PYTHON_3_11,handler='appfunc.handler',code=_lambda.Code.from_asset('function')) | ||
|
||
# Create an API Gateway REST API | ||
api = apigateway.RestApi(self, 'CDKAPI', rest_api_name='CDKAPI', default_integration=LambdaIntegrationNoPermission(lambda_function)) | ||
lambda_function.add_permission(id='1', principal=iam.ServicePrincipal('apigateway.amazonaws.com'), action='lambda:InvokeFunction', source_arn=f'arn:aws:execute-api:{self.region}:{self.account}:{api.rest_api_id}/*/*/*') | ||
|
||
# Create resources and associate the Lambda integration without resource-based policy creation | ||
resource = api.root.add_resource('resource1') | ||
resource.add_method('GET', LambdaIntegrationNoPermission(lambda_function)) | ||
resource = api.root.add_resource('resource2') | ||
resource.add_method('POST', LambdaIntegrationNoPermission(lambda_function)) | ||
resource = api.root.add_resource('resourceN') | ||
resource.add_method('POST', LambdaIntegrationNoPermission(lambda_function)) | ||
|
||
|
||
class LambdaIntegrationNoPermission(apigateway.LambdaIntegration): | ||
def __init__(self, handler, **kwargs): | ||
super().__init__(handler, **kwargs) | ||
def bind(self, method: apigateway.Method): | ||
integration_config = super().bind(method) | ||
permissions = filter(lambda x: isinstance(x, CfnPermission), method.node.children) | ||
# Removing permissions policy for each integration | ||
for p in permissions: | ||
method.node.try_remove_child(p.node.id) | ||
return integration_config |
49 changes: 49 additions & 0 deletions
49
apigw-lambda-wildcard-resourcebasedpolicy-cdk/example-pattern.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
{ | ||
"title": "Amazon API Gateway to AWS Lambda with wildcard resource-based policy", | ||
"description": "Create a REST API with proxy integration to a Lambda function to keep the size of resource-based policy within the allowed hard limit.", | ||
"language": "Python", | ||
"level": "200", | ||
"framework": "CDK", | ||
"introBox": { | ||
"headline": "How it works", | ||
"text": [ | ||
"Currently, in an API Gateway-Lambda setup whenever an user adds an integration, CDK adds a new policy to the Lambda function's resource-based policy.", | ||
"It might result in exceeding the policy size limit for Lambda function which is 20KB.", | ||
"This sample project demonstrates how to use CDK to create a customized integration that would keep the policy size within limit by using wildcards in the resource-based policy." | ||
] | ||
}, | ||
"gitHub": { | ||
"template": { | ||
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/apigw-lambda-wildcard-resourcebasedpolicy-cdk", | ||
"templateURL": "serverless-patterns/apigw-lambda-wildcard-resourcebasedpolicy-cdk", | ||
"projectFolder": "apigw-lambda-wildcard-resourcebasedpolicy-cdk", | ||
"templateFile": "template.yaml" | ||
} | ||
}, | ||
"resources": { | ||
"bullets": [] | ||
}, | ||
"deploy": { | ||
"text": [ | ||
"sam deploy" | ||
] | ||
}, | ||
"testing": { | ||
"text": [ | ||
"See the GitHub repo for detailed testing instructions." | ||
] | ||
}, | ||
"cleanup": { | ||
"text": [ | ||
"Delete the stack: sam delete." | ||
] | ||
}, | ||
"authors": [ | ||
{ | ||
"name": "Saborni Bhattacharya", | ||
"image": "https://drive.google.com/file/d/1AZFquOkafEQRUlrT4hKOtIbt4Cq66SHd/view?usp=sharing", | ||
"bio": "I am Saborni working as a Cloud Engineer at AWS SE Serverless.", | ||
"linkedin": "saborni-bhattacharya-5b523812a" | ||
} | ||
] | ||
} |
7 changes: 7 additions & 0 deletions
7
apigw-lambda-wildcard-resourcebasedpolicy-cdk/function/appfunc.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
# SPDX-License-Identifier: MIT-0 | ||
def handler(event, context): | ||
return { | ||
"body":"Invoked Successfully", | ||
"statusCode": 200 | ||
} |
1 change: 1 addition & 0 deletions
1
apigw-lambda-wildcard-resourcebasedpolicy-cdk/requirements-dev.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pytest==6.2.5 |
2 changes: 2 additions & 0 deletions
2
apigw-lambda-wildcard-resourcebasedpolicy-cdk/requirements.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
aws-cdk-lib==2.95.1 | ||
constructs>=10.0.0,<11.0.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
@echo off | ||
|
||
rem The sole purpose of this script is to make the command | ||
rem | ||
rem source .venv/bin/activate | ||
rem | ||
rem (which activates a Python virtualenv on Linux or Mac OS X) work on Windows. | ||
rem On Windows, this command just runs this batch file (the argument is ignored). | ||
rem | ||
rem Now we don't need to document a Windows command for activating a virtualenv. | ||
|
||
echo Executing .venv\Scripts\activate.bat for you | ||
.venv\Scripts\activate.bat |
Empty file.
Empty file.
15 changes: 15 additions & 0 deletions
15
apigw-lambda-wildcard-resourcebasedpolicy-cdk/tests/unit/test_cdk_apigw_stack.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import aws_cdk as core | ||
import aws_cdk.assertions as assertions | ||
|
||
from cdk_apigw.cdk_apigw_stack import CdkApigwStack | ||
|
||
# example tests. To run these tests, uncomment this file along with the example | ||
# resource in cdk_apigw/cdk_apigw_stack.py | ||
def test_sqs_queue_created(): | ||
app = core.App() | ||
stack = CdkApigwStack(app, "cdk-apigw") | ||
template = assertions.Template.from_stack(stack) | ||
|
||
# template.has_resource_properties("AWS::SQS::Queue", { | ||
# "VisibilityTimeout": 300 | ||
# }) |