├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── recipe-request.md ├── 501-Triggering-Lambda-With-ALB ├── .gitignore ├── README.md ├── cdk-AWS-Cookbook-501 │ ├── .gitignore │ ├── README.md │ ├── app.py │ ├── cdk.json │ ├── cdk_aws_cookbook_501 │ │ ├── __init__.py │ │ └── cdk_aws_cookbook_501_stack.py │ ├── helper.py │ ├── requirements.txt │ ├── setup.py │ └── source.bat └── lambda_function.py ├── 502-Packaging-Libraries-with-Lambda-Layers ├── .gitignore ├── README.md └── lambda_function.py ├── 503-Triggering-Lambda-Functions-on-a-Schedule ├── README.md ├── lambda_function.py └── lambda_function.zip ├── 504-Mounting-an-EFS-Filesystem-to-Lambda ├── .gitignore ├── README.md ├── assume-role-policy.json ├── cdk-AWS-Cookbook-504 │ ├── .gitignore │ ├── README.md │ ├── app.py │ ├── cdk.json │ ├── cdk_aws_cookbook_504 │ │ ├── __init__.py │ │ └── cdk_aws_cookbook_504_stack.py │ ├── helper.py │ ├── requirements.txt │ ├── s3_content │ │ └── Recipe504Test.txt │ ├── setup.py │ └── source.bat ├── lambda_function.py └── lambda_function.zip ├── 505-Running-Trusted-Code-in-Lambda-Using-AWS-Signer ├── .gitignore ├── README.md ├── lambda_function.py └── lambda_function.zip ├── 506-Packaging-Lambda-Code-in-a-Container-Image ├── .gitignore ├── Dockerfile ├── README.md └── app.py ├── 507-Importing-CSV-to-DynamoDB-from-S3 ├── .gitignore ├── README.md ├── assume-role-policy.json ├── lambda_function.py ├── notification-template.json ├── notification.json └── sample_data.csv ├── 508-Reducing-Lambda-Startup-Times-with-Lambda-Concurrency ├── README.md ├── lambda_function.py ├── lambda_function.zip └── response.json ├── 509-Accessing-VPC-Resources-with-Lambda ├── .gitignore ├── README.md ├── cdk-AWS-Cookbook-509 │ ├── .gitignore │ ├── README.md │ ├── app.py │ ├── cdk.json │ ├── cdk_aws_cookbook_509 │ │ ├── __init__.py │ │ └── cdk_aws_cookbook_509_stack.py │ ├── helper.py │ ├── requirements-dev.txt │ ├── requirements.txt │ ├── setup.py │ ├── source.bat │ └── tests │ │ ├── __init__.py │ │ └── unit │ │ ├── __init__.py │ │ └── test_cdk_aws_cookbook_509_stack.py ├── lambda_function.py └── lambda_function.zip ├── LICENSE ├── README.md └── assume-role-policy.json /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/recipe-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Recipe request 3 | about: Suggest a recipe for this Chapter 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your recipe request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe what you'd like to learn** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /501-Triggering-Lambda-With-ALB/.gitignore: -------------------------------------------------------------------------------- 1 | lambda_function.zip -------------------------------------------------------------------------------- /501-Triggering-Lambda-With-ALB/README.md: -------------------------------------------------------------------------------- 1 | # Triggering Lambda With ALB 2 | ## Preparation 3 | This recipe requires some “prep work” which deploys resources that you’ll build the solution on. You will use the AWS CDK to deploy these resources. 4 | 5 | ### In the root of this Chapter’s repo cd to the “501-Triggering-Lambda-With-ALB/cdk-AWS-Cookbook-501” directory and follow the subsequent steps: 6 | ``` 7 | cd 501-Triggering-Lambda-With-ALB/cdk-AWS-Cookbook-501/ 8 | test -d .venv || python3 -m venv .venv 9 | source .venv/bin/activate 10 | pip install --upgrade pip 11 | pip install -r requirements.txt 12 | cdk deploy 13 | ``` 14 | 15 | ### Wait for the cdk deploy command to complete. 16 | 17 | ### We created a helper.py script to let you easily create and export environment variables to make subsequent commands easier. Run the script, and copy the output to your terminal to export variables: 18 | 19 | `python helper.py` 20 | 21 | ### For this recipe, you will need to create a modified environment variable from the output: 22 | 23 | `PUBLIC_SUBNETS=$(echo ${PUBLIC_SUBNETS} | tr -d ',"')` 24 | 25 | ### Navigate up to the main directory for this recipe (out of the “cdk-AWS-Cookbook-501” directory): 26 | 27 | `cd ..` 28 | 29 | 30 | 31 | ## Clean up 32 | ### Delete the listener rule: 33 | 34 | `aws elbv2 delete-rule --rule-arn $RULE_ARN` 35 | 36 | ### Delete the target group: 37 | 38 | `aws elbv2 delete-target-group --target-group-arn $TARGET_GROUP_ARN` 39 | 40 | ### Delete the Lambda function: 41 | 42 | `aws lambda delete-function --function-name AWSCookbook501Lambda` 43 | 44 | ### Delete the Lambda CloudWatch log group: 45 | ``` 46 | aws logs delete-log-group \ 47 | --log-group-name /aws/lambda/AWSCookbook501Lambda 48 | ``` 49 | 50 | ### Go to the cdk-AWS-Cookbook-501 directory: 51 | 52 | `cd cdk-AWS-Cookbook-501/` 53 | 54 | ### To clean up the environment variables, run the helper.py script in this recipe’s cdk- directory with the --unset flag, and copy the output to your terminal to export variables: 55 | 56 | `python helper.py --unset` 57 | 58 | ### Unset the environment variable that you created manually: 59 | ``` 60 | unset LAMBDA_ARN 61 | unset RULE_ARN 62 | unset TARGET_GROUP_ARN 63 | ``` 64 | 65 | ### Use the AWS CDK to destroy the resources, deactivate your Python virtual environment, and go to the root of the chapter: 66 | 67 | `cdk destroy && deactivate && rm -r .venv/ && cd ../..` 68 | 69 | -------------------------------------------------------------------------------- /501-Triggering-Lambda-With-ALB/cdk-AWS-Cookbook-501/.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | package-lock.json 3 | __pycache__ 4 | .pytest_cache 5 | .env 6 | .venv 7 | *.egg-info 8 | 9 | # CDK asset staging directory 10 | .cdk.staging 11 | cdk.out 12 | -------------------------------------------------------------------------------- /501-Triggering-Lambda-With-ALB/cdk-AWS-Cookbook-501/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Welcome to your CDK Python project! 3 | 4 | This is a blank project for Python development with CDK. 5 | 6 | The `cdk.json` file tells the CDK Toolkit how to execute your app. 7 | 8 | This project is set up like a standard Python project. The initialization 9 | process also creates a virtualenv within this project, stored under the `.venv` 10 | directory. To create the virtualenv it assumes that there is a `python3` 11 | (or `python` for Windows) executable in your path with access to the `venv` 12 | package. If for any reason the automatic creation of the virtualenv fails, 13 | you can create the virtualenv manually. 14 | 15 | To manually create a virtualenv on MacOS and Linux: 16 | 17 | ``` 18 | $ python3 -m venv .venv 19 | ``` 20 | 21 | After the init process completes and the virtualenv is created, you can use the following 22 | step to activate your virtualenv. 23 | 24 | ``` 25 | $ source .venv/bin/activate 26 | ``` 27 | 28 | If you are a Windows platform, you would activate the virtualenv like this: 29 | 30 | ``` 31 | % .venv\Scripts\activate.bat 32 | ``` 33 | 34 | Once the virtualenv is activated, you can install the required dependencies. 35 | 36 | ``` 37 | $ pip install -r requirements.txt 38 | ``` 39 | 40 | At this point you can now synthesize the CloudFormation template for this code. 41 | 42 | ``` 43 | $ cdk synth 44 | ``` 45 | 46 | To add additional dependencies, for example other CDK libraries, just add 47 | them to your `setup.py` file and rerun the `pip install -r requirements.txt` 48 | command. 49 | 50 | ## Useful commands 51 | 52 | * `cdk ls` list all stacks in the app 53 | * `cdk synth` emits the synthesized CloudFormation template 54 | * `cdk deploy` deploy this stack to your default AWS account/region 55 | * `cdk diff` compare deployed stack with current state 56 | * `cdk docs` open CDK documentation 57 | 58 | Enjoy! 59 | -------------------------------------------------------------------------------- /501-Triggering-Lambda-With-ALB/cdk-AWS-Cookbook-501/app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import aws_cdk as cdk 4 | 5 | from cdk_aws_cookbook_501.cdk_aws_cookbook_501_stack import CdkAwsCookbook501Stack 6 | 7 | 8 | app = cdk.App() 9 | CdkAwsCookbook501Stack(app, "cdk-aws-cookbook-501") 10 | 11 | app.synth() 12 | -------------------------------------------------------------------------------- /501-Triggering-Lambda-With-ALB/cdk-AWS-Cookbook-501/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "python3 app.py", 3 | "context": { 4 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": false, 5 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": false, 6 | "@aws-cdk/core:stackRelativeExports": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /501-Triggering-Lambda-With-ALB/cdk-AWS-Cookbook-501/cdk_aws_cookbook_501/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AWSCookbook/Serverless/ad39607b2901774b99056505e0ed03386c10ef7e/501-Triggering-Lambda-With-ALB/cdk-AWS-Cookbook-501/cdk_aws_cookbook_501/__init__.py -------------------------------------------------------------------------------- /501-Triggering-Lambda-With-ALB/cdk-AWS-Cookbook-501/cdk_aws_cookbook_501/cdk_aws_cookbook_501_stack.py: -------------------------------------------------------------------------------- 1 | from constructs import Construct 2 | from aws_cdk import ( 3 | aws_ec2 as ec2, 4 | aws_elasticloadbalancingv2 as alb, 5 | Stack, 6 | CfnOutput, 7 | ) 8 | 9 | 10 | class CdkAwsCookbook501Stack(Stack): 11 | 12 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 13 | super().__init__(scope, construct_id, **kwargs) 14 | 15 | # The code that defines your stack goes here 16 | public_subnets = ec2.SubnetConfiguration( 17 | name="PUBLIC", 18 | subnet_type=ec2.SubnetType.PUBLIC, 19 | cidr_mask=24 20 | ) 21 | 22 | # create VPC 23 | vpc = ec2.Vpc( 24 | self, 25 | 'AWS-Cookbook-VPC-501', 26 | cidr='10.10.0.0/23', 27 | subnet_configuration=[public_subnets] 28 | ) 29 | 30 | albSecurityGroup = ec2.SecurityGroup( 31 | self, 32 | 'albSecurityGroup', 33 | vpc=vpc, 34 | allow_all_outbound=True, 35 | description='Security Group for the ALB', 36 | ) 37 | 38 | albSecurityGroup.add_ingress_rule( 39 | peer=ec2.Peer.ipv4("0.0.0.0/0"), 40 | connection=ec2.Port.tcp(80), 41 | description='Allow HTTP from the world', 42 | remote_rule=False 43 | ) 44 | 45 | LoadBalacner = alb.ApplicationLoadBalancer( 46 | self, 47 | 'LoadBalacner', 48 | vpc=vpc, 49 | internet_facing=True, 50 | security_group=albSecurityGroup, 51 | vpc_subnets=ec2.SubnetSelection( 52 | one_per_az=False, 53 | subnet_type=ec2.SubnetType('PUBLIC') 54 | ) 55 | ) 56 | 57 | Listener = alb.ApplicationListener( 58 | self, 59 | 'listener80', 60 | load_balancer=LoadBalacner, 61 | open=False, 62 | port=80, 63 | protocol=alb.ApplicationProtocol('HTTP') 64 | ) 65 | 66 | Listener.add_action( 67 | 'Fixed', 68 | action=alb.ListenerAction.fixed_response( 69 | status_code=200, 70 | message_body="AWS Cookbook Fixed Content for ALB" 71 | ) 72 | ) 73 | 74 | # outputs 75 | CfnOutput( 76 | self, 'LoadBalancerDns', 77 | value=LoadBalacner.load_balancer_dns_name 78 | ) 79 | 80 | CfnOutput( 81 | self, 82 | 'ListenerArn', 83 | value=Listener.listener_arn 84 | ) 85 | 86 | CfnOutput( 87 | self, 88 | 'VpcId', 89 | value=vpc.vpc_id 90 | ) 91 | 92 | CfnOutput( 93 | self, 94 | 'AlbArn', 95 | value=LoadBalacner.load_balancer_arn 96 | ) 97 | 98 | public_subnets = vpc.select_subnets(subnet_type=ec2.SubnetType.PUBLIC) 99 | 100 | CfnOutput( 101 | self, 102 | 'PublicSubnets', 103 | value=', '.join(map(str, public_subnets.subnet_ids)) 104 | ) 105 | -------------------------------------------------------------------------------- /501-Triggering-Lambda-With-ALB/cdk-AWS-Cookbook-501/helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import boto3 3 | import argparse 4 | 5 | 6 | def change_case(str): 7 | res = [str[0]] 8 | for c in str[1:]: 9 | if c in ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'): 10 | res.append('_') 11 | res.append(c) 12 | elif c in ('123456789'): 13 | res.append('_') 14 | res.append(c) 15 | else: 16 | res.append(c.upper()) 17 | 18 | return ''.join(res) 19 | 20 | 21 | parser = argparse.ArgumentParser(description="Generate commands to set and unset environment variables") 22 | parser.add_argument('--unset', action='store_true', help="Generate commands to unset environment variables by setting this flag") 23 | 24 | args = parser.parse_args() 25 | 26 | os.environ['AWS_DEFAULT_REGION'] = os.environ.get('AWS_REGION') 27 | 28 | cfn = boto3.client('cloudformation') 29 | stackname = os.path.basename(os.getcwd()).lower() 30 | response = cfn.describe_stacks(StackName=stackname) 31 | unsets = [] 32 | sets = [] 33 | 34 | outputs = response["Stacks"][0]["Outputs"] 35 | print("Copy and paste the commands below into your terminal") 36 | print("") 37 | for output in outputs: 38 | if ', ' in output["OutputValue"]: 39 | sets.append(change_case(output["OutputKey"]) + "='" + ', '.join('"{}"'.format(word) for word in output["OutputValue"].split(", ")) + "'") 40 | else: 41 | sets.append(change_case(output["OutputKey"]) + "='" + output["OutputValue"] + "'") 42 | unsets.append("unset " + change_case(output["OutputKey"])) 43 | 44 | if (args.unset): 45 | print('\n'.join(map(str, unsets))) 46 | else: 47 | print('\n'.join(map(str, sets))) 48 | 49 | print("") 50 | -------------------------------------------------------------------------------- /501-Triggering-Lambda-With-ALB/cdk-AWS-Cookbook-501/requirements.txt: -------------------------------------------------------------------------------- 1 | -e . 2 | boto3 3 | -------------------------------------------------------------------------------- /501-Triggering-Lambda-With-ALB/cdk-AWS-Cookbook-501/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | 4 | with open("README.md") as fp: 5 | long_description = fp.read() 6 | 7 | 8 | setuptools.setup( 9 | name="cdk_aws_cookbook_501", 10 | version="0.0.1", 11 | 12 | description="An empty CDK Python app", 13 | long_description=long_description, 14 | long_description_content_type="text/markdown", 15 | 16 | author="author", 17 | 18 | package_dir={"": "cdk_aws_cookbook_501"}, 19 | packages=setuptools.find_packages(where="cdk_aws_cookbook_501"), 20 | 21 | install_requires=[ 22 | "aws-cdk-lib>=2.0.0rc1", 23 | "constructs>=10.0.0", 24 | ], 25 | 26 | python_requires=">=3.6", 27 | 28 | classifiers=[ 29 | "Development Status :: 4 - Beta", 30 | 31 | "Intended Audience :: Developers", 32 | 33 | "License :: OSI Approved :: Apache Software License", 34 | 35 | "Programming Language :: JavaScript", 36 | "Programming Language :: Python :: 3 :: Only", 37 | "Programming Language :: Python :: 3.6", 38 | "Programming Language :: Python :: 3.7", 39 | "Programming Language :: Python :: 3.8", 40 | 41 | "Topic :: Software Development :: Code Generators", 42 | "Topic :: Utilities", 43 | 44 | "Typing :: Typed", 45 | ], 46 | ) 47 | -------------------------------------------------------------------------------- /501-Triggering-Lambda-With-ALB/cdk-AWS-Cookbook-501/source.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem The sole purpose of this script is to make the command 4 | rem 5 | rem source .venv/bin/activate 6 | rem 7 | rem (which activates a Python virtualenv on Linux or Mac OS X) work on Windows. 8 | rem On Windows, this command just runs this batch file (the argument is ignored). 9 | rem 10 | rem Now we don't need to document a Windows command for activating a virtualenv. 11 | 12 | echo Executing .venv\Scripts\activate.bat for you 13 | .venv\Scripts\activate.bat 14 | -------------------------------------------------------------------------------- /501-Triggering-Lambda-With-ALB/lambda_function.py: -------------------------------------------------------------------------------- 1 | import json 2 | def lambda_handler(event, context): 3 | return { 4 | "statusCode": 200, 5 | "body": json.dumps('This AWSCookbook Lambda function was invoked from an Application Load Balancer!\n') 6 | } 7 | -------------------------------------------------------------------------------- /502-Packaging-Libraries-with-Lambda-Layers/.gitignore: -------------------------------------------------------------------------------- 1 | python 2 | lambda_function.zip 3 | requests-layer.zip 4 | response.json -------------------------------------------------------------------------------- /502-Packaging-Libraries-with-Lambda-Layers/README.md: -------------------------------------------------------------------------------- 1 | # Packaging Libraries with Lambda Layers 2 | 3 | 4 | ## Clean up 5 | ### Delete the Lambda function: 6 | 7 | `aws lambda delete-function --function-name AWSCookbook502Lambda` 8 | 9 | ### Delete the Lambda CloudWatch log group that was created automatically: 10 | ``` 11 | aws logs delete-log-group \ 12 | --log-group-name /aws/lambda/AWSCookbook502Lambda 13 | ``` 14 | 15 | ### Delete the Lambda Layer: 16 | ``` 17 | aws lambda delete-layer-version \ 18 | --layer-name AWSCookbook502RequestsLayer \ 19 | --version-number 1 20 | ``` 21 | 22 | ### Unset the environment variable that you created manually: 23 | ``` 24 | unset LAYER_VERSION_ARN 25 | unset LAMBDA_ARN 26 | ``` 27 | -------------------------------------------------------------------------------- /502-Packaging-Libraries-with-Lambda-Layers/lambda_function.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | import requests 3 | 4 | SITE = "https://www.amazon.com/" # URL of the site to check, stored in the site environment variable 5 | EXPECTED = "shopping" # String expected to be on the page, stored in the expected environment variable 6 | 7 | 8 | def validate(res): 9 | '''Return False to trigger the canary 10 | 11 | Currently this simply checks whether the EXPECTED string is present. 12 | However, you could modify this to perform any number of arbitrary 13 | checks on the contents of SITE. 14 | ''' 15 | return EXPECTED in res 16 | 17 | 18 | def lambda_handler(event, context): 19 | print('Checking {} '.format(SITE)) 20 | try: 21 | req = requests.get(SITE, headers={'User-Agent': 'AWS Lambda'}) 22 | if not validate(str(req.text)): 23 | raise Exception('Validation failed') 24 | except: 25 | print('Check failed!') 26 | raise 27 | else: 28 | print('Check passed!') 29 | return "Completed" 30 | finally: 31 | print('Check complete at {}'.format(str(datetime.now()))) 32 | -------------------------------------------------------------------------------- /503-Triggering-Lambda-Functions-on-a-Schedule/README.md: -------------------------------------------------------------------------------- 1 | # Triggering Lambda Functions on a Schedule 2 | ## Preparation 3 | In the root of this Chapter’s repo cd to the “503-Triggering-Lambda-Functions-on-a-Schedule” directory and follow the subsequent steps: 4 | 5 | ### Zip up the lambda_function.py provided in the repository: 6 | 7 | `zip lambda_function.zip lambda_function.py` 8 | 9 | ### Create a Lambda function that we will trigger: 10 | ``` 11 | LAMBDA_ARN=$(aws lambda create-function \ 12 | --function-name AWSCookbook503Lambda \ 13 | --runtime python3.8 \ 14 | --package-type "Zip" \ 15 | --zip-file fileb://lambda_function.zip \ 16 | --handler lambda_function.lambda_handler --publish \ 17 | --role \ 18 | arn:aws:iam::$AWS_ACCOUNT_ID:role/AWSCookbookLambdaRole \ 19 | --output text --query FunctionArn) 20 | ``` 21 | 22 | 23 | ## Clean up 24 | ### Remove the target from the rule: 25 | ``` 26 | aws events remove-targets --rule "EveryMinuteEvent" \ 27 | --ids "1" 28 | ``` 29 | 30 | ### Delete the rule: 31 | 32 | `aws events delete-rule --name "EveryMinuteEvent"` 33 | 34 | ### Delete the Lambda function: 35 | 36 | `aws lambda delete-function --function-name AWSCookbook503Lambda` 37 | 38 | ### Delete the Lambda CloudWatch log group: 39 | ``` 40 | aws logs delete-log-group \ 41 | --log-group-name /aws/lambda/AWSCookbook503Lambda 42 | ``` 43 | 44 | ### Unset the environment variable that you created manually: 45 | ``` 46 | unset LAMBDA_ARN 47 | unset RULE_ARN 48 | ``` 49 | -------------------------------------------------------------------------------- /503-Triggering-Lambda-Functions-on-a-Schedule/lambda_function.py: -------------------------------------------------------------------------------- 1 | import os 2 | from datetime import datetime 3 | 4 | 5 | def lambda_handler(event, context): 6 | print('AWS Cookbook Lambda function run at {}'.format(str(datetime.now()))) 7 | -------------------------------------------------------------------------------- /503-Triggering-Lambda-Functions-on-a-Schedule/lambda_function.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AWSCookbook/Serverless/ad39607b2901774b99056505e0ed03386c10ef7e/503-Triggering-Lambda-Functions-on-a-Schedule/lambda_function.zip -------------------------------------------------------------------------------- /504-Mounting-an-EFS-Filesystem-to-Lambda/.gitignore: -------------------------------------------------------------------------------- 1 | response.json 2 | -------------------------------------------------------------------------------- /504-Mounting-an-EFS-Filesystem-to-Lambda/README.md: -------------------------------------------------------------------------------- 1 | # Mounting an EFS Filesystem to Lambda Functions 2 | ## Preparation 3 | This recipe requires some “prep work” which deploys resources that you’ll build the solution on. You will use the AWS CDK to deploy these resources 4 | 5 | ### In the root of this Chapter’s repo cd to the “504-Mounting-an-EFS-Filesystem-to-Lambda/cdk-AWS-Cookbook-504” directory and follow the subsequent steps: 6 | ``` 7 | cd 504-Mounting-an-EFS-Filesystem-to-Lambda/cdk-AWS-Cookbook-504/ 8 | test -d .venv || python3 -m venv .venv 9 | source .venv/bin/activate 10 | pip install --upgrade pip 11 | pip install -r requirements.txt 12 | cdk deploy 13 | ``` 14 | 15 | ### Wait for the cdk deploy command to complete. 16 | 17 | ### We created a helper.py script to let you easily create and export environment variables to make subsequent commands easier. Run the script, and copy the output to your terminal to export variables: 18 | 19 | `python helper.py` 20 | 21 | ### For this recipe, you will need to create a modified environment variable from the output: 22 | 23 | `ISOLATED_SUBNETS=$(echo ${ISOLATED_SUBNETS} | tr -d ' "')` 24 | 25 | ### Navigate up to the main directory for this recipe (out of the “cdk-AWS-Cookbook-504” directory) 26 | 27 | `cd ..` 28 | 29 | 30 | 31 | ## Clean up 32 | ### Delete the Lambda function: 33 | 34 | `aws lambda delete-function --function-name AWSCookbook504Lambda` 35 | 36 | ### Delete the Lambda CloudWatch log group: 37 | ``` 38 | aws logs delete-log-group \ 39 | --log-group-name /aws/lambda/AWSCookbook504Lambda 40 | ``` 41 | 42 | ### Detach the LambdaVPCAccessExecutionPolicy from the role: 43 | ``` 44 | aws iam detach-role-policy --role-name AWSCookbook504Role \ 45 | --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole 46 | ``` 47 | ### Delete the IAM Role: 48 | 49 | `aws iam delete-role --role-name AWSCookbook504Role` 50 | 51 | ### Remove the ingress rule to the EFS File System’s Security group that allows access on port tcp 2049 from the Lambda’s Security Group: 52 | ``` 53 | aws ec2 revoke-security-group-ingress \ 54 | --protocol tcp --port 2049 \ 55 | --source-group $LAMBDA_SG_ID \ 56 | --group-id $EFS_SECURITY_GROUP 57 | ``` 58 | 59 | ### Delete the security group that you created for the Lambda function: 60 | 61 | `aws ec2 delete-security-group --group-id $LAMBDA_SG_ID` 62 | 63 | ### Go to the cdk-AWS-Cookbook-504 directory: 64 | 65 | `cd cdk-AWS-Cookbook-504/` 66 | 67 | ### To clean up the environment variables, run the helper.py script in this recipe’s cdk- directory with the --unset flag, and copy the output to your terminal to export variables: 68 | 69 | `python helper.py --unset` 70 | 71 | ### Unset the environment variable that you created manually: 72 | ``` 73 | unset LAMBDA_ARN 74 | unset LAMBDA_SG_ID 75 | ``` 76 | 77 | ### Use the AWS CDK to destroy the resources, deactivate your Python virtual environment, and go to the root of the chapter: 78 | 79 | `cdk destroy && deactivate && rm -r .venv/ && cd ../..` 80 | 81 | -------------------------------------------------------------------------------- /504-Mounting-an-EFS-Filesystem-to-Lambda/assume-role-policy.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Effect": "Allow", 6 | "Principal": { 7 | "Service": "lambda.amazonaws.com" 8 | }, 9 | "Action": "sts:AssumeRole" 10 | } 11 | ] 12 | } 13 | 14 | -------------------------------------------------------------------------------- /504-Mounting-an-EFS-Filesystem-to-Lambda/cdk-AWS-Cookbook-504/.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | package-lock.json 3 | __pycache__ 4 | .pytest_cache 5 | .env 6 | .venv 7 | *.egg-info 8 | 9 | # CDK asset staging directory 10 | .cdk.staging 11 | cdk.out 12 | -------------------------------------------------------------------------------- /504-Mounting-an-EFS-Filesystem-to-Lambda/cdk-AWS-Cookbook-504/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Welcome to your CDK Python project! 3 | 4 | This is a blank project for Python development with CDK. 5 | 6 | The `cdk.json` file tells the CDK Toolkit how to execute your app. 7 | 8 | This project is set up like a standard Python project. The initialization 9 | process also creates a virtualenv within this project, stored under the `.venv` 10 | directory. To create the virtualenv it assumes that there is a `python3` 11 | (or `python` for Windows) executable in your path with access to the `venv` 12 | package. If for any reason the automatic creation of the virtualenv fails, 13 | you can create the virtualenv manually. 14 | 15 | To manually create a virtualenv on MacOS and Linux: 16 | 17 | ``` 18 | $ python3 -m venv .venv 19 | ``` 20 | 21 | After the init process completes and the virtualenv is created, you can use the following 22 | step to activate your virtualenv. 23 | 24 | ``` 25 | $ source .venv/bin/activate 26 | ``` 27 | 28 | If you are a Windows platform, you would activate the virtualenv like this: 29 | 30 | ``` 31 | % .venv\Scripts\activate.bat 32 | ``` 33 | 34 | Once the virtualenv is activated, you can install the required dependencies. 35 | 36 | ``` 37 | $ pip install -r requirements.txt 38 | ``` 39 | 40 | At this point you can now synthesize the CloudFormation template for this code. 41 | 42 | ``` 43 | $ cdk synth 44 | ``` 45 | 46 | To add additional dependencies, for example other CDK libraries, just add 47 | them to your `setup.py` file and rerun the `pip install -r requirements.txt` 48 | command. 49 | 50 | ## Useful commands 51 | 52 | * `cdk ls` list all stacks in the app 53 | * `cdk synth` emits the synthesized CloudFormation template 54 | * `cdk deploy` deploy this stack to your default AWS account/region 55 | * `cdk diff` compare deployed stack with current state 56 | * `cdk docs` open CDK documentation 57 | 58 | Enjoy! 59 | -------------------------------------------------------------------------------- /504-Mounting-an-EFS-Filesystem-to-Lambda/cdk-AWS-Cookbook-504/app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import aws_cdk as cdk 4 | 5 | from cdk_aws_cookbook_504.cdk_aws_cookbook_504_stack import CdkAwsCookbook504Stack 6 | 7 | 8 | app = cdk.App() 9 | CdkAwsCookbook504Stack(app, "cdk-aws-cookbook-504") 10 | 11 | app.synth() 12 | -------------------------------------------------------------------------------- /504-Mounting-an-EFS-Filesystem-to-Lambda/cdk-AWS-Cookbook-504/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "python3 app.py", 3 | "context": { 4 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": false, 5 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": false, 6 | "@aws-cdk/core:stackRelativeExports": false 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /504-Mounting-an-EFS-Filesystem-to-Lambda/cdk-AWS-Cookbook-504/cdk_aws_cookbook_504/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AWSCookbook/Serverless/ad39607b2901774b99056505e0ed03386c10ef7e/504-Mounting-an-EFS-Filesystem-to-Lambda/cdk-AWS-Cookbook-504/cdk_aws_cookbook_504/__init__.py -------------------------------------------------------------------------------- /504-Mounting-an-EFS-Filesystem-to-Lambda/cdk-AWS-Cookbook-504/cdk_aws_cookbook_504/cdk_aws_cookbook_504_stack.py: -------------------------------------------------------------------------------- 1 | from constructs import Construct 2 | from aws_cdk import ( 3 | aws_ec2 as ec2, 4 | aws_iam as iam, 5 | aws_s3 as s3, 6 | aws_s3_deployment, 7 | aws_efs, 8 | Stack, 9 | CfnOutput, 10 | RemovalPolicy, 11 | ) 12 | 13 | 14 | class CdkAwsCookbook504Stack(Stack): 15 | 16 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 17 | super().__init__(scope, construct_id, **kwargs) 18 | 19 | # create s3 bucket 20 | s3_Bucket = s3.Bucket( 21 | self, 22 | "AWS-Cookbook-Recipe-504", 23 | removal_policy=RemovalPolicy.DESTROY, 24 | auto_delete_objects=True 25 | ) 26 | 27 | s3_deployment = aws_s3_deployment.BucketDeployment( 28 | self, 29 | 'S3Deployment', 30 | destination_bucket=s3_Bucket, 31 | sources=[aws_s3_deployment.Source.asset("./s3_content")], 32 | retain_on_delete=False 33 | ) 34 | 35 | isolated_subnets = ec2.SubnetConfiguration( 36 | name="ISOLATED", 37 | subnet_type=ec2.SubnetType.PRIVATE_ISOLATED, 38 | cidr_mask=24 39 | ) 40 | 41 | # create VPC 42 | vpc = ec2.Vpc( 43 | self, 44 | 'AWS-Cookbook-VPC-504', 45 | cidr='10.10.0.0/23', 46 | subnet_configuration=[isolated_subnets] 47 | ) 48 | 49 | vpc.add_gateway_endpoint( 50 | 's3GateWayEndPoint', 51 | service=ec2.GatewayVpcEndpointAwsService('s3'), 52 | subnets=[ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_ISOLATED)], 53 | ) 54 | 55 | efs_security_group = ec2.SecurityGroup( 56 | self, 57 | 'efs_security_group', 58 | description='Security Group for the EFS File System', 59 | allow_all_outbound=True, 60 | vpc=vpc 61 | ) 62 | 63 | file_system = aws_efs.FileSystem( 64 | self, 65 | 'Filesystem', 66 | vpc=vpc, 67 | removal_policy=RemovalPolicy.DESTROY, 68 | security_group=efs_security_group, 69 | vpc_subnets=ec2.SubnetSelection( 70 | one_per_az=False, 71 | subnet_type=ec2.SubnetType.PRIVATE_ISOLATED 72 | ) 73 | ) 74 | 75 | # -------- Begin EC2 Helper --------- 76 | vpc.add_interface_endpoint( 77 | 'VPCSSMInterfaceEndpoint', 78 | service=ec2.InterfaceVpcEndpointAwsService('ssm'), # Find names with - aws ec2 describe-vpc-endpoint-services | jq '.ServiceNames' 79 | private_dns_enabled=True, 80 | subnets=ec2.SubnetSelection( 81 | one_per_az=False, 82 | subnet_type=ec2.SubnetType.PRIVATE_ISOLATED 83 | ), 84 | ) 85 | 86 | vpc.add_interface_endpoint( 87 | 'VPCEC2MessagesInterfaceEndpoint', 88 | service=ec2.InterfaceVpcEndpointAwsService('ec2messages'), # Find names with - aws ec2 describe-vpc-endpoint-services | jq '.ServiceNames' 89 | private_dns_enabled=True, 90 | subnets=ec2.SubnetSelection( 91 | one_per_az=False, 92 | subnet_type=ec2.SubnetType.PRIVATE_ISOLATED 93 | ), 94 | ) 95 | 96 | vpc.add_interface_endpoint( 97 | 'VPCSSMMessagesInterfaceEndpoint', 98 | service=ec2.InterfaceVpcEndpointAwsService('ssmmessages'), # Find names with - aws ec2 describe-vpc-endpoint-services | jq '.ServiceNames' 99 | private_dns_enabled=True, 100 | subnets=ec2.SubnetSelection( 101 | one_per_az=False, 102 | subnet_type=ec2.SubnetType.PRIVATE_ISOLATED 103 | ), 104 | ) 105 | 106 | ami = ec2.MachineImage.latest_amazon_linux( 107 | generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2, 108 | edition=ec2.AmazonLinuxEdition.STANDARD, 109 | virtualization=ec2.AmazonLinuxVirt.HVM, 110 | storage=ec2.AmazonLinuxStorage.GENERAL_PURPOSE 111 | ) 112 | 113 | user_data = ec2.UserData.for_linux() 114 | user_data.add_commands( 115 | 'sudo yum -y install amazon-efs-utils', 116 | 'sudo mkdir /mnt/efs', 117 | 'sudo mount -t efs -o iam,tls ' + file_system.file_system_id + ' /mnt/efs', 118 | 'aws s3 cp s3://' + s3_Bucket.bucket_name + '/Recipe504Test.txt /mnt/efs', 119 | 'sudo umount /mnt/efs' 120 | ) 121 | 122 | iam_role = iam.Role(self, "InstanceSSM", assumed_by=iam.ServicePrincipal("ec2.amazonaws.com")) 123 | 124 | iam_role.add_managed_policy(iam.ManagedPolicy.from_aws_managed_policy_name("service-role/AmazonEC2RoleforSSM")) 125 | 126 | instance = ec2.Instance( 127 | self, 128 | "Instance", 129 | instance_type=ec2.InstanceType("t3.nano"), 130 | machine_image=ami, 131 | role=iam_role, 132 | user_data=user_data, 133 | vpc=vpc, 134 | ) 135 | 136 | instance.node.add_dependency(s3_deployment) 137 | 138 | CfnOutput( 139 | self, 140 | 'InstanceId', 141 | value=instance.instance_id 142 | ) 143 | # -------- End EC2 Helper --------- 144 | 145 | # allow connection from ec2 instance to the file_system SG 146 | file_system.connections.allow_from( 147 | instance.connections, ec2.Port.tcp(2049), "Ingress") 148 | 149 | access_point = aws_efs.AccessPoint( 150 | self, 151 | 'AccessPoint', 152 | file_system=file_system 153 | ) 154 | 155 | # outputs 156 | 157 | CfnOutput( 158 | self, 159 | 'VpcId', 160 | value=vpc.vpc_id 161 | ) 162 | 163 | CfnOutput( 164 | self, 165 | 'FileSystemId', 166 | value=file_system.file_system_id 167 | ) 168 | 169 | CfnOutput( 170 | self, 171 | 'AccessPointArn', 172 | value=access_point.access_point_arn 173 | ) 174 | 175 | CfnOutput( 176 | self, 177 | 'EfsSecurityGroup', 178 | value=efs_security_group.security_group_id 179 | ) 180 | 181 | isolated_subnets = vpc.select_subnets(subnet_type=ec2.SubnetType.PRIVATE_ISOLATED) 182 | 183 | CfnOutput( 184 | self, 185 | 'IsolatedSubnets', 186 | value=', '.join(map(str, isolated_subnets.subnet_ids)) 187 | ) 188 | -------------------------------------------------------------------------------- /504-Mounting-an-EFS-Filesystem-to-Lambda/cdk-AWS-Cookbook-504/helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import boto3 3 | import argparse 4 | 5 | 6 | def change_case(str): 7 | res = [str[0]] 8 | for c in str[1:]: 9 | if c in ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'): 10 | res.append('_') 11 | res.append(c) 12 | elif c in ('123456789'): 13 | res.append('_') 14 | res.append(c) 15 | else: 16 | res.append(c.upper()) 17 | 18 | return ''.join(res) 19 | 20 | 21 | parser = argparse.ArgumentParser(description="Generate commands to set and unset environment variables") 22 | parser.add_argument('--unset', action='store_true', help="Generate commands to unset environment variables by setting this flag") 23 | 24 | args = parser.parse_args() 25 | 26 | os.environ['AWS_DEFAULT_REGION'] = os.environ.get('AWS_REGION') 27 | 28 | cfn = boto3.client('cloudformation') 29 | stackname = os.path.basename(os.getcwd()).lower() 30 | response = cfn.describe_stacks(StackName=stackname) 31 | unsets = [] 32 | sets = [] 33 | 34 | outputs = response["Stacks"][0]["Outputs"] 35 | print("Copy and paste the commands below into your terminal") 36 | print("") 37 | for output in outputs: 38 | if ', ' in output["OutputValue"]: 39 | sets.append(change_case(output["OutputKey"]) + "='" + ', '.join('"{}"'.format(word) for word in output["OutputValue"].split(", ")) + "'") 40 | else: 41 | sets.append(change_case(output["OutputKey"]) + "='" + output["OutputValue"] + "'") 42 | unsets.append("unset " + change_case(output["OutputKey"])) 43 | 44 | if (args.unset): 45 | print('\n'.join(map(str, unsets))) 46 | else: 47 | print('\n'.join(map(str, sets))) 48 | 49 | print("") 50 | -------------------------------------------------------------------------------- /504-Mounting-an-EFS-Filesystem-to-Lambda/cdk-AWS-Cookbook-504/requirements.txt: -------------------------------------------------------------------------------- 1 | -e . 2 | boto3 3 | -------------------------------------------------------------------------------- /504-Mounting-an-EFS-Filesystem-to-Lambda/cdk-AWS-Cookbook-504/s3_content/Recipe504Test.txt: -------------------------------------------------------------------------------- 1 | Recipe 504 Test Data -------------------------------------------------------------------------------- /504-Mounting-an-EFS-Filesystem-to-Lambda/cdk-AWS-Cookbook-504/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | 4 | with open("README.md") as fp: 5 | long_description = fp.read() 6 | 7 | 8 | setuptools.setup( 9 | name="cdk_aws_cookbook_504", 10 | version="0.0.1", 11 | 12 | description="An empty CDK Python app", 13 | long_description=long_description, 14 | long_description_content_type="text/markdown", 15 | 16 | author="author", 17 | 18 | package_dir={"": "cdk_aws_cookbook_504"}, 19 | packages=setuptools.find_packages(where="cdk_aws_cookbook_504"), 20 | 21 | install_requires=[ 22 | "aws-cdk-lib>=2.0.0rc1", 23 | "constructs>=10.0.0", 24 | ], 25 | 26 | python_requires=">=3.6", 27 | 28 | classifiers=[ 29 | "Development Status :: 4 - Beta", 30 | 31 | "Intended Audience :: Developers", 32 | 33 | "License :: OSI Approved :: Apache Software License", 34 | 35 | "Programming Language :: JavaScript", 36 | "Programming Language :: Python :: 3 :: Only", 37 | "Programming Language :: Python :: 3.6", 38 | "Programming Language :: Python :: 3.7", 39 | "Programming Language :: Python :: 3.8", 40 | 41 | "Topic :: Software Development :: Code Generators", 42 | "Topic :: Utilities", 43 | 44 | "Typing :: Typed", 45 | ], 46 | ) 47 | -------------------------------------------------------------------------------- /504-Mounting-an-EFS-Filesystem-to-Lambda/cdk-AWS-Cookbook-504/source.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem The sole purpose of this script is to make the command 4 | rem 5 | rem source .venv/bin/activate 6 | rem 7 | rem (which activates a Python virtualenv on Linux or Mac OS X) work on Windows. 8 | rem On Windows, this command just runs this batch file (the argument is ignored). 9 | rem 10 | rem Now we don't need to document a Windows command for activating a virtualenv. 11 | 12 | echo Executing .venv\Scripts\activate.bat for you 13 | .venv\Scripts\activate.bat 14 | -------------------------------------------------------------------------------- /504-Mounting-an-EFS-Filesystem-to-Lambda/lambda_function.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import logging 3 | import os 4 | 5 | logger = logging.getLogger() 6 | logger.setLevel(logging.INFO) 7 | 8 | def lambda_handler(event, context): 9 | 10 | try: 11 | os.system("touch /mnt/efs/awscookbook1.txt") 12 | os.system("touch /mnt/efs/awscookbook2.txt") 13 | os.system("touch /mnt/efs/awscookbook3.txt") 14 | for root, dirs, files in os.walk("/mnt/efs/"): 15 | for filename in files: 16 | print(filename) 17 | logger.info("SUCCESS: Connected to EFS via /mnt/efs/ and put 3 files!") 18 | return("SUCCESS: Connected to EFS via /mnt/efs/ and put 3 files!") 19 | except: 20 | logger.error("ERROR: Could not connect to EFS") 21 | return("ERROR: Could not connect to EFS") 22 | -------------------------------------------------------------------------------- /504-Mounting-an-EFS-Filesystem-to-Lambda/lambda_function.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AWSCookbook/Serverless/ad39607b2901774b99056505e0ed03386c10ef7e/504-Mounting-an-EFS-Filesystem-to-Lambda/lambda_function.zip -------------------------------------------------------------------------------- /505-Running-Trusted-Code-in-Lambda-Using-AWS-Signer/.gitignore: -------------------------------------------------------------------------------- 1 | my-private-key.pem 2 | my-certificate.pem -------------------------------------------------------------------------------- /505-Running-Trusted-Code-in-Lambda-Using-AWS-Signer/README.md: -------------------------------------------------------------------------------- 1 | # Running Trusted Code in Lambda Using Code Signing 2 | ## Preparation 3 | In the root of this Chapter’s repo cd to the “505-Running-Trusted-Code-in-Lambda-Using-AWS-Signer” directory and follow the subsequent steps: 4 | 5 | ### Set a unique suffix to use for the S3 bucket name and signing profile: 6 | ``` 7 | RANDOM_STRING=$(aws secretsmanager get-random-password \ 8 | --exclude-punctuation --exclude-uppercase \ 9 | --password-length 6 --require-each-included-type \ 10 | --output text \ 11 | --query RandomPassword) 12 | ``` 13 | 14 | ### Create a Destination S3 bucket to store the signed code: 15 | 16 | `aws s3api create-bucket --bucket awscookbook505-dst-$RANDOM_STRING` 17 | 18 | ### Create a Source S3 Bucket to store the raw code: 19 | 20 | `aws s3api create-bucket --bucket awscookbook505-src-$RANDOM_STRING` 21 | 22 | ### Enable Versioning for the Source S3 bucket (this is required by AWS Signer): 23 | ``` 24 | aws s3api put-bucket-versioning \ 25 | --bucket awscookbook505-src-$RANDOM_STRING \ 26 | --versioning-configuration Status=Enabled 27 | ``` 28 | 29 | ### Copy the provided lambda_function.zip file that contains the source code to the Source S3 bucket: 30 | 31 | `aws s3 cp ./lambda_function.zip s3://awscookbook505-src-$RANDOM_STRING` 32 | 33 | ## Clean up 34 | ### Delete the Lambda function: 35 | 36 | `aws lambda delete-function --function-name AWSCookbook505Lambda` 37 | 38 | ### Delete the Lambda CloudWatch log group. This may not exist if you didn’t execute your Lambda function: 39 | ``` 40 | aws logs delete-log-group \ 41 | --log-group-name /aws/lambda/AWSCookbook505Lambda 42 | ``` 43 | 44 | ### Revoke the signature: 45 | ``` 46 | aws signer revoke-signature --job-id $SIGNING_JOB_ID \ 47 | --reason "No longer using" 48 | ``` 49 | 50 | ### Delete the code signing config: 51 | ``` 52 | aws lambda delete-code-signing-config \ 53 | --code-signing-config-arn $CODE_SIGNING_CONFIG_ARN 54 | ``` 55 | 56 | ### Delete the signing profile: 57 | ``` 58 | aws signer cancel-signing-profile \ 59 | --profile-name AWSCookbook505_$RANDOM_STRING 60 | ``` 61 | 62 | ### Delete all versions of files in the source S3 bucket: 63 | ``` 64 | aws s3api delete-objects \ 65 | --bucket awscookbook505-src-$RANDOM_STRING \ 66 | --delete "$(aws s3api list-object-versions \ 67 | --bucket "awscookbook505-src-$RANDOM_STRING" \ 68 | --output=json \ 69 | --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}')" 70 | ``` 71 | 72 | ### Delete the source S3 bucket 73 | 74 | `aws s3api delete-bucket --bucket awscookbook505-src-$RANDOM_STRING` 75 | 76 | ### Delete the signed code in the destination bucket 77 | 78 | `aws s3 rm s3://awscookbook505-dst-$RANDOM_STRING/$OBJECT_KEY` 79 | 80 | ### Delete the destination S3 bucket 81 | 82 | `aws s3api delete-bucket --bucket awscookbook505-dst-$RANDOM_STRING` 83 | 84 | ### Unset the environment variable that you created manually: 85 | ``` 86 | unset RANDOM_STRING 87 | unset SIGNING_PROFILE_ARN 88 | unset CODE_SIGNING_CONFIG_ARN 89 | unset OBJ_VER_ID 90 | unset SIGNING_JOB_ID 91 | unset LAMBDA_ARN 92 | unset OBJECT_KEY 93 | ``` 94 | -------------------------------------------------------------------------------- /505-Running-Trusted-Code-in-Lambda-Using-AWS-Signer/lambda_function.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | 4 | def lambda_handler(event, context): 5 | print('AWS Cookbook Function run at {}'.format(str(datetime.now()))) 6 | -------------------------------------------------------------------------------- /505-Running-Trusted-Code-in-Lambda-Using-AWS-Signer/lambda_function.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AWSCookbook/Serverless/ad39607b2901774b99056505e0ed03386c10ef7e/505-Running-Trusted-Code-in-Lambda-Using-AWS-Signer/lambda_function.zip -------------------------------------------------------------------------------- /506-Packaging-Lambda-Code-in-a-Container-Image/.gitignore: -------------------------------------------------------------------------------- 1 | response.json -------------------------------------------------------------------------------- /506-Packaging-Lambda-Code-in-a-Container-Image/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/lambda/python:3.8 2 | 3 | COPY app.py ./ 4 | CMD ["app.handler"] -------------------------------------------------------------------------------- /506-Packaging-Lambda-Code-in-a-Container-Image/README.md: -------------------------------------------------------------------------------- 1 | # Packaging Lambda Code in a Container Image 2 | ## Preparation 3 | ### Create an ECR repository to store your Docker image: 4 | 5 | `aws ecr create-repository --repository-name aws-cookbook-506repo` 6 | 7 | 8 | 9 | ## Clean up 10 | ### Delete the Lambda function: 11 | 12 | `aws lambda delete-function --function-name AWSCookbook506Lambda` 13 | 14 | ### Delete the Lambda CloudWatch log group: 15 | ``` 16 | aws logs delete-log-group \ 17 | --log-group-name /aws/lambda/AWSCookbook506Lambda 18 | ``` 19 | 20 | ### Delete the images from your local machine: 21 | ``` 22 | docker image rm lambda-cookbook-container:latest 23 | docker image rm \ 24 | $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/aws-cookbook-506repo:latest 25 | ``` 26 | 27 | ### Remove the image from ECR: 28 | ``` 29 | aws ecr batch-delete-image \ 30 | --repository-name aws-cookbook-506repo \ 31 | --image-ids imageTag=latest 32 | ``` 33 | 34 | ### Delete the now empty repository: 35 | ``` 36 | aws ecr delete-repository \ 37 | --repository-name aws-cookbook-506repo 38 | ``` 39 | 40 | ### Unset the environment variable that you created manually 41 | 42 | `unset LAMBDA_ARN` 43 | -------------------------------------------------------------------------------- /506-Packaging-Lambda-Code-in-a-Container-Image/app.py: -------------------------------------------------------------------------------- 1 | import sys 2 | def handler(event, context): 3 | return 'Hello from the AWS Cookbook ' + sys.version + '!' -------------------------------------------------------------------------------- /507-Importing-CSV-to-DynamoDB-from-S3/.gitignore: -------------------------------------------------------------------------------- 1 | response.json 2 | lambda_function.zip 3 | lambda_function.zip 4 | notification.json -------------------------------------------------------------------------------- /507-Importing-CSV-to-DynamoDB-from-S3/README.md: -------------------------------------------------------------------------------- 1 | # Automating CSV Import into DynamoDB from S3 with Lambda 2 | 3 | ## Clean up 4 | ### Delete the DynamoDB table: 5 | ``` 6 | aws dynamodb delete-table \ 7 | --table-name 'AWSCookbook507' 8 | ``` 9 | 10 | ### Delete the Lambda function: 11 | 12 | `aws lambda delete-function --function-name AWSCookbook507Lambda` 13 | 14 | ### Delete the Lambda CloudWatch log group: 15 | ``` 16 | aws logs delete-log-group \ 17 | --log-group-name /aws/lambda/AWSCookbook507Lambda 18 | ``` 19 | 20 | ### Detach the AmazonS3ReadOnlyAccess from the role: 21 | ``` 22 | aws iam detach-role-policy --role-name AWSCookbook507Lambda \ 23 | --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess 24 | ``` 25 | 26 | ### Detach the AmazonDynamoDBFullAccess policy from the role: 27 | ``` 28 | aws iam detach-role-policy --role-name AWSCookbook507Lambda \ 29 | --policy-arn arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess 30 | ``` 31 | 32 | ### Detach the AWSLambdaBasicExecutionRole policy from the role: 33 | ``` 34 | aws iam detach-role-policy --role-name AWSCookbook507Lambda \ 35 | --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole 36 | ``` 37 | 38 | ### Delete the IAM Role: 39 | 40 | `aws iam delete-role --role-name AWSCookbook507Lambda` 41 | 42 | ### Delete the file you copied to your S3 bucket: 43 | 44 | `aws s3 rm s3://awscookbook507-$RANDOM_STRING/sample_data.csv` 45 | 46 | ### Delete the S3 bucket: 47 | 48 | `aws s3api delete-bucket --bucket awscookbook507-$RANDOM_STRING` 49 | 50 | ### Unset the environment variable that you created manually : 51 | ``` 52 | unset LAMBDA_ARN 53 | unset RANDOM_STRING 54 | ``` 55 | -------------------------------------------------------------------------------- /507-Importing-CSV-to-DynamoDB-from-S3/assume-role-policy.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Effect": "Allow", 6 | "Principal": { 7 | "Service": "lambda.amazonaws.com" 8 | }, 9 | "Action": "sts:AssumeRole" 10 | } 11 | ] 12 | } 13 | 14 | -------------------------------------------------------------------------------- /507-Importing-CSV-to-DynamoDB-from-S3/lambda_function.py: -------------------------------------------------------------------------------- 1 | import json 2 | import boto3 3 | import os 4 | import csv 5 | import codecs 6 | import sys 7 | 8 | s3 = boto3.resource('s3') 9 | dynamodb = boto3.resource('dynamodb') 10 | 11 | bucket = os.environ['bucket'] 12 | key = 'sample_data.csv' 13 | tableName = 'AWSCookbook507' 14 | 15 | def lambda_handler(event, context): 16 | 17 | try: 18 | obj = s3.Object(bucket, key).get()['Body'] 19 | except: 20 | print("Error: S3 error") 21 | 22 | batch_size = 100 23 | batch = [] 24 | 25 | for row in csv.DictReader(codecs.getreader('utf-8')(obj)): 26 | if len(batch) >= batch_size: 27 | write_table(batch) 28 | batch.clear() 29 | 30 | batch.append(row) 31 | 32 | if batch: 33 | write_table(batch) 34 | 35 | return { 36 | 'statusCode': 200, 37 | 'body': json.dumps('Success: Import complete') 38 | } 39 | 40 | 41 | def write_table(rows): 42 | try: 43 | table = dynamodb.Table(tableName) 44 | except: 45 | print("Error: Table error") 46 | 47 | try: 48 | with table.batch_writer() as batch: 49 | for i in range(len(rows)): 50 | batch.put_item( 51 | Item=rows[i] 52 | ) 53 | except: 54 | print("Error: Import failed") -------------------------------------------------------------------------------- /507-Importing-CSV-to-DynamoDB-from-S3/notification-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "LambdaFunctionConfigurations": [ 3 | { 4 | "Id": "awscookbook507event", 5 | "LambdaFunctionArn": "LAMBDA_ARN", 6 | "Events": [ 7 | "s3:ObjectCreated:*" 8 | ], 9 | "Filter": { 10 | "Key": { 11 | "FilterRules": [ 12 | { 13 | "Name": "prefix", 14 | "Value": "sample_data.csv" 15 | } 16 | ] 17 | } 18 | } 19 | } 20 | ] 21 | } 22 | 23 | -------------------------------------------------------------------------------- /507-Importing-CSV-to-DynamoDB-from-S3/notification.json: -------------------------------------------------------------------------------- 1 | { 2 | "LambdaFunctionConfigurations": [ 3 | { 4 | "Id": "awscookbook507event", 5 | "LambdaFunctionArn": "arn:aws:lambda:us-east-1:611652777867:function:AWSCookbook507Lambda", 6 | "Events": [ 7 | "s3:ObjectCreated:*" 8 | ], 9 | "Filter": { 10 | "Key": { 11 | "FilterRules": [ 12 | { 13 | "Name": "prefix", 14 | "Value": "sample_data.csv" 15 | } 16 | ] 17 | } 18 | } 19 | } 20 | ] 21 | } 22 | 23 | -------------------------------------------------------------------------------- /507-Importing-CSV-to-DynamoDB-from-S3/sample_data.csv: -------------------------------------------------------------------------------- 1 | UserID,Name 2 | 1000,Susan 3 | 1001,John 4 | 1002,Becky 5 | 1003,Mike 6 | 1004,Martha 7 | 1005,James 8 | 1006,Katie 9 | 1007,Roger 10 | 1008,Olivia 11 | 1009,Thomas -------------------------------------------------------------------------------- /508-Reducing-Lambda-Startup-Times-with-Lambda-Concurrency/README.md: -------------------------------------------------------------------------------- 1 | # Reducing Lambda Startup Times with Lambda Concurrency 2 | 3 | 4 | ## Clean up 5 | ### Delete the Lambda function 6 | 7 | `aws lambda delete-function --function-name AWSCookbook508Lambda` 8 | 9 | ### Delete the Lambda CloudWatch log group 10 | ``` 11 | aws logs delete-log-group \ 12 | --log-group-name /aws/lambda/AWSCookbook508Lambda 13 | ``` 14 | -------------------------------------------------------------------------------- /508-Reducing-Lambda-Startup-Times-with-Lambda-Concurrency/lambda_function.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | import time 3 | 4 | 5 | def lambda_handler(event, context): 6 | time.sleep(5) 7 | print('AWS Cookbook Function run at {}'.format(str(datetime.now()))) 8 | -------------------------------------------------------------------------------- /508-Reducing-Lambda-Startup-Times-with-Lambda-Concurrency/lambda_function.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AWSCookbook/Serverless/ad39607b2901774b99056505e0ed03386c10ef7e/508-Reducing-Lambda-Startup-Times-with-Lambda-Concurrency/lambda_function.zip -------------------------------------------------------------------------------- /508-Reducing-Lambda-Startup-Times-with-Lambda-Concurrency/response.json: -------------------------------------------------------------------------------- 1 | null -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/.gitignore: -------------------------------------------------------------------------------- 1 | redis* 2 | response.json 3 | -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/README.md: -------------------------------------------------------------------------------- 1 | # Accessing VPC Resources with Lambda 2 | ## Preparation 3 | 4 | This recipe requires some “prep work” which deploys resources that you’ll build the solution on. You will use the AWS CDK to deploy these resources 5 | 6 | ### In the root of this Chapter’s repo cd to the “509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509” directory and follow the subsequent steps: 7 | ``` 8 | cd 509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509 9 | test -d .venv || python3 -m venv .venv 10 | source .venv/bin/activate 11 | pip install --upgrade pip 12 | pip install -r requirements.txt 13 | cdk deploy 14 | ``` 15 | 16 | ### Wait for the cdk deploy command to complete. 17 | 18 | ### We created a helper.py script to let you easily create and export environment variables to make subsequent commands easier. Run the script, and copy the output to your terminal to export variables: 19 | 20 | `python helper.py` 21 | 22 | ### For this recipe, you will need to create a modified environment variable from the output: 23 | 24 | `TRIMMED_ISOLATED_SUBNETS=$(echo ${ISOLATED_SUBNETS} | tr -d ' "')` 25 | 26 | ### We also need modify this variable to have the right format 27 | `ISOLATED_SUBNETS=$(echo ${ISOLATED_SUBNETS} | tr -d ',"')` 28 | 29 | ### Go up a directory. 30 | ``` 31 | cd .. 32 | ``` 33 | 34 | ## Clean up 35 | ### Delete the Cache Cluster: 36 | ``` 37 | aws elasticache delete-cache-cluster \ 38 | --cache-cluster-id "AWSCookbook509CacheCluster" 39 | ``` 40 | 41 | ### Delete the Cache Subnet Group: 42 | ``` 43 | aws elasticache delete-cache-subnet-group \ 44 | --cache-subnet-group-name "AWSCookbook509CacheSG" 45 | ``` 46 | 47 | ### Delete the Lambda function: 48 | 49 | `aws lambda delete-function --function-name AWSCookbook509Lambda` 50 | 51 | ### Delete the Lambda CloudWatch log group: 52 | ``` 53 | aws logs delete-log-group \ 54 | --log-group-name /aws/lambda/AWSCookbook509Lambda 55 | ``` 56 | 57 | ### Detach the AWSLambdaBasicExecutionRole policy from the role: 58 | ``` 59 | aws iam detach-role-policy --role-name AWSCookbook509Lambda \ 60 | --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole 61 | ``` 62 | 63 | ### Delete the IAM Role: 64 | 65 | `aws iam delete-role --role-name AWSCookbook509Lambda` 66 | 67 | ### Delete the Lambda Security Group: 68 | 69 | `aws ec2 delete-security-group --group-id $LAMBDA_SG_ID` 70 | 71 | ### To clean up the environment variables, run the helper.py script in this recipe’s cdk- directory with the --unset flag, and copy the output to your terminal to export variables: 72 | 73 | `python helper.py --unset` 74 | 75 | ### Unset the environment variable that you created manually: 76 | ``` 77 | unset LAMBDA_SG_ID 78 | unset LAMBDA_ARN 79 | unset SUBNET_IDS 80 | unset TRIMMED_ISOLATED_SUBNETS 81 | ``` 82 | 83 | ### Use the AWS CDK to destroy the resources, deactivate your Python virtual environment, and go to the root of the chapter: 84 | 85 | `cdk destroy && deactivate && rm -r .venv/ && cd ../..` 86 | -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | package-lock.json 3 | __pycache__ 4 | .pytest_cache 5 | .venv 6 | *.egg-info 7 | 8 | # CDK asset staging directory 9 | .cdk.staging 10 | cdk.out 11 | -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Welcome to your CDK Python project! 3 | 4 | This is a blank project for Python development with CDK. 5 | 6 | The `cdk.json` file tells the CDK Toolkit how to execute your app. 7 | 8 | This project is set up like a standard Python project. The initialization 9 | process also creates a virtualenv within this project, stored under the `.venv` 10 | directory. To create the virtualenv it assumes that there is a `python3` 11 | (or `python` for Windows) executable in your path with access to the `venv` 12 | package. If for any reason the automatic creation of the virtualenv fails, 13 | you can create the virtualenv manually. 14 | 15 | To manually create a virtualenv on MacOS and Linux: 16 | 17 | ``` 18 | $ python3 -m venv .venv 19 | ``` 20 | 21 | After the init process completes and the virtualenv is created, you can use the following 22 | step to activate your virtualenv. 23 | 24 | ``` 25 | $ source .venv/bin/activate 26 | ``` 27 | 28 | If you are a Windows platform, you would activate the virtualenv like this: 29 | 30 | ``` 31 | % .venv\Scripts\activate.bat 32 | ``` 33 | 34 | Once the virtualenv is activated, you can install the required dependencies. 35 | 36 | ``` 37 | $ pip install -r requirements.txt 38 | ``` 39 | 40 | At this point you can now synthesize the CloudFormation template for this code. 41 | 42 | ``` 43 | $ cdk synth 44 | ``` 45 | 46 | To add additional dependencies, for example other CDK libraries, just add 47 | them to your `setup.py` file and rerun the `pip install -r requirements.txt` 48 | command. 49 | 50 | ## Useful commands 51 | 52 | * `cdk ls` list all stacks in the app 53 | * `cdk synth` emits the synthesized CloudFormation template 54 | * `cdk deploy` deploy this stack to your default AWS account/region 55 | * `cdk diff` compare deployed stack with current state 56 | * `cdk docs` open CDK documentation 57 | 58 | Enjoy! 59 | -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | 4 | import aws_cdk as cdk 5 | 6 | from cdk_aws_cookbook_509.cdk_aws_cookbook_509_stack import CdkAwsCookbook509Stack 7 | 8 | 9 | app = cdk.App() 10 | CdkAwsCookbook509Stack(app, "cdk-aws-cookbook-509", 11 | # If you don't specify 'env', this stack will be environment-agnostic. 12 | # Account/Region-dependent features and context lookups will not work, 13 | # but a single synthesized template can be deployed anywhere. 14 | 15 | # Uncomment the next line to specialize this stack for the AWS Account 16 | # and Region that are implied by the current CLI configuration. 17 | 18 | #env=cdk.Environment(account=os.getenv('CDK_DEFAULT_ACCOUNT'), region=os.getenv('CDK_DEFAULT_REGION')), 19 | 20 | # Uncomment the next line if you know exactly what Account and Region you 21 | # want to deploy the stack to. */ 22 | 23 | #env=cdk.Environment(account='123456789012', region='us-east-1'), 24 | 25 | # For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html 26 | ) 27 | 28 | app.synth() 29 | -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "python3 app.py", 3 | "watch": { 4 | "include": [ 5 | "**" 6 | ], 7 | "exclude": [ 8 | "README.md", 9 | "cdk*.json", 10 | "requirements*.txt", 11 | "source.bat", 12 | "**/__init__.py", 13 | "python/__pycache__", 14 | "tests" 15 | ] 16 | }, 17 | "context": { 18 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true, 19 | "@aws-cdk/core:stackRelativeExports": true, 20 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": true, 21 | "@aws-cdk/aws-lambda:recognizeVersionProps": true, 22 | "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/cdk_aws_cookbook_509/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AWSCookbook/Serverless/ad39607b2901774b99056505e0ed03386c10ef7e/509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/cdk_aws_cookbook_509/__init__.py -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/cdk_aws_cookbook_509/cdk_aws_cookbook_509_stack.py: -------------------------------------------------------------------------------- 1 | from constructs import Construct 2 | from aws_cdk import ( 3 | aws_ec2 as ec2, 4 | aws_s3 as s3, 5 | aws_s3_deployment, 6 | aws_iam as iam, 7 | aws_rds as rds, 8 | aws_logs as logs, 9 | aws_lambda, 10 | custom_resources, 11 | Stack, 12 | CfnOutput 13 | ) 14 | 15 | 16 | class CdkAwsCookbook509Stack(Stack): 17 | 18 | def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: 19 | super().__init__(scope, construct_id, **kwargs) 20 | 21 | isolated_subnets = ec2.SubnetConfiguration( 22 | name="ISOLATED", 23 | subnet_type=ec2.SubnetType.PRIVATE_ISOLATED, 24 | cidr_mask=24 25 | ) 26 | 27 | # create VPC 28 | vpc = ec2.Vpc( 29 | self, 30 | 'AWS-Cookbook-VPC', 31 | cidr='10.10.0.0/23', 32 | subnet_configuration=[isolated_subnets] 33 | ) 34 | 35 | cache_security_group = ec2.SecurityGroup( 36 | self, 37 | 'cache_security_group', 38 | description='Security Group for the ElastiCache cluster', 39 | allow_all_outbound=True, 40 | vpc=vpc 41 | ) 42 | 43 | # outputs 44 | 45 | CfnOutput( 46 | self, 47 | 'VpcId', 48 | value=vpc.vpc_id 49 | ) 50 | 51 | CfnOutput( 52 | self, 53 | 'CacheSecurityGroup', 54 | value=cache_security_group.security_group_id 55 | ) 56 | 57 | isolated_subnets = vpc.select_subnets(subnet_type=ec2.SubnetType.PRIVATE_ISOLATED) 58 | 59 | CfnOutput( 60 | self, 61 | 'IsolatedSubnets', 62 | value=', '.join(map(str, isolated_subnets.subnet_ids)) 63 | ) -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/helper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import boto3 3 | import argparse 4 | 5 | 6 | def change_case(str): 7 | res = [str[0]] 8 | for c in str[1:]: 9 | if c in ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'): 10 | res.append('_') 11 | res.append(c) 12 | elif c in ('123456789'): 13 | res.append('_') 14 | res.append(c) 15 | else: 16 | res.append(c.upper()) 17 | 18 | return ''.join(res) 19 | 20 | 21 | parser = argparse.ArgumentParser(description="Generate commands to set and unset environment variables") 22 | parser.add_argument('--unset', action='store_true', help="Generate commands to unset environment variables by setting this flag") 23 | 24 | args = parser.parse_args() 25 | 26 | os.environ['AWS_DEFAULT_REGION'] = os.environ.get('AWS_REGION') 27 | 28 | cfn = boto3.client('cloudformation') 29 | stackname = os.path.basename(os.getcwd()).lower() 30 | response = cfn.describe_stacks(StackName=stackname) 31 | unsets = [] 32 | sets = [] 33 | 34 | outputs = response["Stacks"][0]["Outputs"] 35 | print("Copy and paste the commands below into your terminal") 36 | print("") 37 | for output in outputs: 38 | if ', ' in output["OutputValue"]: 39 | sets.append(change_case(output["OutputKey"]) + "='" + ', '.join('"{}"'.format(word) for word in output["OutputValue"].split(", ")) + "'") 40 | else: 41 | sets.append(change_case(output["OutputKey"]) + "='" + output["OutputValue"] + "'") 42 | unsets.append("unset " + change_case(output["OutputKey"])) 43 | 44 | if (args.unset): 45 | print('\n'.join(map(str, unsets))) 46 | else: 47 | print('\n'.join(map(str, sets))) 48 | 49 | print("") 50 | -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/requirements-dev.txt: -------------------------------------------------------------------------------- 1 | pytest==6.2.5 2 | -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/requirements.txt: -------------------------------------------------------------------------------- 1 | -e . 2 | boto3 -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | 4 | with open("README.md") as fp: 5 | long_description = fp.read() 6 | 7 | 8 | setuptools.setup( 9 | name="cdk_aws_cookbook_509", 10 | version="0.0.1", 11 | 12 | description="An empty CDK Python app", 13 | long_description=long_description, 14 | long_description_content_type="text/markdown", 15 | 16 | author="author", 17 | 18 | package_dir={"": "cdk_aws_cookbook_509"}, 19 | packages=setuptools.find_packages(where="cdk_aws_cookbook_509"), 20 | 21 | install_requires=[ 22 | "aws-cdk-lib>=2.0.0rc1", 23 | "constructs>=10.0.0", 24 | ], 25 | 26 | python_requires=">=3.6", 27 | 28 | classifiers=[ 29 | "Development Status :: 4 - Beta", 30 | 31 | "Intended Audience :: Developers", 32 | 33 | "License :: OSI Approved :: Apache Software License", 34 | 35 | "Programming Language :: JavaScript", 36 | "Programming Language :: Python :: 3 :: Only", 37 | "Programming Language :: Python :: 3.6", 38 | "Programming Language :: Python :: 3.7", 39 | "Programming Language :: Python :: 3.8", 40 | 41 | "Topic :: Software Development :: Code Generators", 42 | "Topic :: Utilities", 43 | 44 | "Typing :: Typed", 45 | ], 46 | ) 47 | -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/source.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem The sole purpose of this script is to make the command 4 | rem 5 | rem source .venv/bin/activate 6 | rem 7 | rem (which activates a Python virtualenv on Linux or Mac OS X) work on Windows. 8 | rem On Windows, this command just runs this batch file (the argument is ignored). 9 | rem 10 | rem Now we don't need to document a Windows command for activating a virtualenv. 11 | 12 | echo Executing .venv\Scripts\activate.bat for you 13 | .venv\Scripts\activate.bat 14 | -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AWSCookbook/Serverless/ad39607b2901774b99056505e0ed03386c10ef7e/509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/tests/__init__.py -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/tests/unit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AWSCookbook/Serverless/ad39607b2901774b99056505e0ed03386c10ef7e/509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/tests/unit/__init__.py -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/cdk-AWS-Cookbook-509/tests/unit/test_cdk_aws_cookbook_509_stack.py: -------------------------------------------------------------------------------- 1 | import aws_cdk as core 2 | import aws_cdk.assertions as assertions 3 | 4 | from cdk_aws_cookbook_509.cdk_aws_cookbook_509_stack import CdkAwsCookbook509Stack 5 | 6 | # example tests. To run these tests, uncomment this file along with the example 7 | # resource in cdk_aws_cookbook_509/cdk_aws_cookbook_509_stack.py 8 | def test_sqs_queue_created(): 9 | app = core.App() 10 | stack = CdkAwsCookbook509Stack(app, "cdk-aws-cookbook-509") 11 | template = assertions.Template.from_stack(stack) 12 | 13 | # template.has_resource_properties("AWS::SQS::Queue", { 14 | # "VisibilityTimeout": 300 15 | # }) 16 | -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/lambda_function.py: -------------------------------------------------------------------------------- 1 | import uuid 2 | import redis 3 | 4 | def handler(event, context): 5 | r = redis.Redis(host=event['hostname'], port=6379, db=0) 6 | set_uuid = uuid.uuid4().hex 7 | r.set('uuid', set_uuid) 8 | get_uuid = r.get('uuid') 9 | if get_uuid == set_uuid: 10 | print("Success: Got value %s from redis" % (get_uuid)) 11 | else: 12 | raise Exception("Error: Exception") 13 | 14 | return "Got value from redis: " + get_uuid -------------------------------------------------------------------------------- /509-Accessing-VPC-Resources-with-Lambda/lambda_function.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AWSCookbook/Serverless/ad39607b2901774b99056505e0ed03386c10ef7e/509-Accessing-VPC-Resources-with-Lambda/lambda_function.zip -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 John Culkin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chapter5 2 | ## Set and export your default region: 3 | 4 | `export AWS_REGION=us-east-1` 5 | 6 | ## Set your AWS ACCOUNT ID:: 7 | 8 | `AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)` 9 | 10 | ## Validate AWS Cli Setup and access: 11 | 12 | `aws ec2 describe-instances` 13 | -------------------------------------------------------------------------------- /assume-role-policy.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Effect": "Allow", 6 | "Principal": { 7 | "Service": "lambda.amazonaws.com" 8 | }, 9 | "Action": "sts:AssumeRole" 10 | } 11 | ] 12 | } 13 | 14 | --------------------------------------------------------------------------------