├── .all-contributorsrc ├── 00-intro-and-welcome.md ├── 01-install-aws-cloud-development-kit-cdk-and-create-a-new-project.md ├── 02-build-and-deploy-a-sample-aws-cloud-development-kit-stack-to-aws.md ├── 03-review-an-aws-cloud-formation-stack-deployed-with-aws-cdk.md ├── 04-clear-an-initial-aws-cdk-stack-to-start-building-an-app-from-scratch.md ├── 05-create-and-deploy-a-lambda-function-with-aws-cdk.md ├── 06-review-and-execute-a-lambda-function-deployed-with-cdk-in-aws-console.md ├── 07-change-the-properties-of-a-lambda-function-deployed-with-aws-cdk.md ├── 08-attach-an-api-gateway-to-a-lambda-function-deployed-with-aws-cdk.md ├── 09-pass-environment-variables-to-a-lambda-function-deployed-with-aws-cdk.md ├── 10-run-lambda-functions-built-with-cdk-locally-using-aws-sam.md ├── 11-create-and-deploy-an-s3-bucket-with-aws-cdk.md ├── 12-make-the-contents-of-an-s3-bucket-deployed-with-cdk-public.md ├── 13-create-an-s3-event-notification-to-trigger-a-lambda-function-on-file-upload.md ├── 14-use-a-bucket-deployment-to-upload-a-file-to-s3-when-deploying-a-cdk-stack.md ├── 15-create-a-custom-aws-cdk-construct.md ├── 16-create-a-dynamo-db-table-with-aws-cdk.md ├── 17-get-all-items-from-a-dynamo-db-table-deployed-with-cdk-using-document-client-api.md ├── 18-debug-permission-issues-and-allow-a-lambda-function-to-access-data-from-a-dynamo-db-table.md ├── 19-adding-data-to-a-dynamo-db-table-with-put-operation.md ├── 20-delete-an-item-from-a-dynamo-db-table-with-delete-operation.md ├── 21-add-external-dependencies-to-an-aws-lambda-function-deployed-with-cdk.md ├── 22-connect-react-app-to-a-serverless-backend-deployed-with-cdk-and-fix-cors-issues.md ├── 23-add-a-custom-cloud-formation-stack-output-with-cdk.md ├── 24-deploy-a-static-website-to-s3-with-aws-cdk.md ├── 25-deploy-a-site-with-https-support-behind-a-cdn-with-cdk.md ├── 26-destroy-an-aws-cdk-stack.md ├── README.md ├── course-project ├── README.md └── community-solutions.md └── images ├── 03-review-an-aws-cloud-formation-stack-deployed-with-aws-cdk-trigger-image.png ├── 07-change-the-properties-of-a-lambda-function-deployed-with-aws-cdk-lambda-config-image.png ├── 08-attach-an-api-gateway-to-a-lambda-function-deployed-with-aws-cdk-api-gateway.png ├── 09-pass-environment-variables-to-a-lambda-function-deployed-with-aws-cdk-env-image.png ├── 11-create-and-deploy-an-s3-bucket-with-aws-cdk-s3-buckets.png ├── 12-make-the-contents-of-an-s3-bucket-deployed-with-cdk-public-closed-buckets.png ├── 15-create-a-custom-aws-cdk-construct-custom-construct-images.png ├── 16-create-a-dynamo-db-table-with-aws-cdk-dynamodb-image.png ├── 16-create-a-dynamo-db-table-with-aws-cdk-storage-illustration.png └── 25-deploy-a-site-with-https-support-behind-a-cdn-with-cdk-cdn.png /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "contributors": [ 8 | { 9 | "login": "laurosilvacom", 10 | "name": "Lauro Silva", 11 | "avatar_url": "https://avatars2.githubusercontent.com/u/57044804?v=4", 12 | "profile": "https://laurosilva.com", 13 | "contributions": [ 14 | "review" 15 | ] 16 | }, 17 | { 18 | "login": "edieblu", 19 | "name": "edieblu", 20 | "avatar_url": "https://avatars3.githubusercontent.com/u/17270662?v=4", 21 | "profile": "http://includejs.dev", 22 | "contributions": [ 23 | "content", 24 | "userTesting" 25 | ] 26 | }, 27 | { 28 | "login": "MaggieAppleton", 29 | "name": "Appleton", 30 | "avatar_url": "https://avatars0.githubusercontent.com/u/5599295?v=4", 31 | "profile": "http://maggieappleton.com", 32 | "contributions": [ 33 | "design" 34 | ] 35 | }, 36 | { 37 | "login": "lsminter", 38 | "name": "Lucas Minter", 39 | "avatar_url": "https://avatars1.githubusercontent.com/u/26470581?v=4", 40 | "profile": "https://github.com/lsminter", 41 | "contributions": [ 42 | "review" 43 | ] 44 | }, 45 | { 46 | "login": "darkwark", 47 | "name": "Kamil Khadeyev", 48 | "avatar_url": "https://avatars0.githubusercontent.com/u/1868217?v=4", 49 | "profile": "http://darkwark.com", 50 | "contributions": [ 51 | "design" 52 | ] 53 | }, 54 | { 55 | "login": "Creeland", 56 | "name": "Creeland A. Provinsal ", 57 | "avatar_url": "https://avatars2.githubusercontent.com/u/518406?v=4", 58 | "profile": "https://github.com/Creeland", 59 | "contributions": [ 60 | "content" 61 | ] 62 | }, 63 | { 64 | "login": "zacjones93", 65 | "name": "Zac Jones", 66 | "avatar_url": "https://avatars2.githubusercontent.com/u/6188161?v=4", 67 | "profile": "https://zacjones.io", 68 | "contributions": [ 69 | "content" 70 | ] 71 | }, 72 | { 73 | "login": "wjohnson85", 74 | "name": "William Johnson", 75 | "avatar_url": "https://avatars2.githubusercontent.com/u/40403549?v=4", 76 | "profile": "https://williamjohnson.dev/", 77 | "contributions": [ 78 | "review" 79 | ] 80 | }, 81 | { 82 | "login": "theianjones", 83 | "name": "Ian Jones", 84 | "avatar_url": "https://avatars2.githubusercontent.com/u/4407263?v=4", 85 | "profile": "https://ianjones.us/", 86 | "contributions": [ 87 | "userTesting" 88 | ] 89 | }, 90 | { 91 | "login": "pixelsortr", 92 | "name": "Pixel", 93 | "avatar_url": "https://avatars0.githubusercontent.com/u/54180211?v=4", 94 | "profile": "https://github.com/pixelsortr", 95 | "contributions": [ 96 | "content" 97 | ] 98 | }, 99 | { 100 | "login": "MrZakos", 101 | "name": "Zakos", 102 | "avatar_url": "https://avatars2.githubusercontent.com/u/999613?v=4", 103 | "profile": "https://github.com/MrZakos", 104 | "contributions": [ 105 | "bug" 106 | ] 107 | }, 108 | { 109 | "login": "codeandcats", 110 | "name": "Ben", 111 | "avatar_url": "https://avatars0.githubusercontent.com/u/6035934?v=4", 112 | "profile": "http://bendaniel.io", 113 | "contributions": [ 114 | "content" 115 | ] 116 | }, 117 | { 118 | "login": "pgrimaud", 119 | "name": "Pierre Grimaud", 120 | "avatar_url": "https://avatars1.githubusercontent.com/u/1866496?v=4", 121 | "profile": "https://github.com/pgrimaud", 122 | "contributions": [ 123 | "content" 124 | ] 125 | } 126 | ], 127 | "contributorsPerLine": 7, 128 | "projectName": "build-an-app-with-the-AWS-cloud-development-kit-notes", 129 | "projectOwner": "eggheadio-projects", 130 | "repoType": "github", 131 | "repoHost": "https://github.com", 132 | "skipCi": true 133 | } 134 | -------------------------------------------------------------------------------- /00-intro-and-welcome.md: -------------------------------------------------------------------------------- 1 | # Intro and Welcome 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-build-and-deploy-a-sample-aws-cloud-development-kit-stack-to-aws)** 4 | 5 | **[💻 Code](https://github.com/tlakomy/egghead-aws-cdk-workshop)** 6 | 7 | Hi and welcome! This document contains some of the things that I had to lookup while I was going through this course. I hope you find them useful too! 8 | 9 | ## Install Libraries 10 | 11 | You need to ensure that all CDK packages (core, s3, etc.) have the same version. The recommended version for all CDK packages is `1.31.0`. 12 | 13 | You can install an old version of an npm package using the `@` syntax: 14 | 15 | ``` 16 | npm install @ 17 | ``` 18 | ``` 19 | npm i @aws-cdk/aws-s3@1.31.0 20 | ``` 21 | 22 | ## What is a lambda function? 23 | 24 | * `lambda` means function as a service, where you, the developer, don't have to worry about managing servers, just the functions that need to be executed. 25 | 26 | * The function can be triggered by multiple sources like **API Gateway** (`http` requests), as well as changes to the **Dynamo DB** database or `s3` storage bucket. 27 | 28 | * `lambda` functions can be written in a variety of different languages. 29 | 30 | If you prefer a video tutorial, follow this [one](https://egghead.io/lessons/aws-wtf-is-aws-lambda). 31 | 32 | ## Create an admin user with IAM and configure AWS CLI to enable programmatic access to AWS 33 | 34 | Go to [AWS Management Account](https://aws.amazon.com/console/) and either create a new account or log in. 35 | 36 | * In the **Find Services** section look for **IAM** 37 | 38 | * Once you are in **Identity and Access Management** select **Users** from the sidebar. 39 | 40 | * Click on **Add user** and create a new **admin-user** and select both **Programmatic access** AND **AWS Management Console access** 41 | 42 | * Under **Permissions** create a new **admin** group and create an **admin-user** for this group. 43 | 44 | * Create a group called **AdminUsers** and check **AdministratorAccess** under Policy Name then click **Create Group**. 45 | 46 | * You can skip the **tag** section and click on **Create user**. 47 | 48 | * Make sure to save your **access key** and **password** (Secret Access Key) as this is the only time that they will be displayed (👍 you can download them as a `.csv` file) 49 | 50 | Here for the [📹 video tutorial](https://egghead.io/lessons/egghead-create-an-admin-user-with-iam-and-configure-aws-cli-to-enable-programmatic-access-to-aws). 51 | 52 | ## Avoid aws charges by setting up a billing alarm 53 | 54 | * Log into your `aws` console as a `root` user then search for **Billing**. 55 | 56 | * Scroll down and check your usage in **Top Free Tier Services by Usage** 57 | 58 | * Under **Services** search for **CloudWatch**, click on **Billing** and then **Create alarm**. 59 | 60 | * Leave the default configuration then add a threshold value, for example: $5 (meaning you'll get a notification whenever you spend more than $5). 61 | 62 | * On the next page, choose: **Create new topic**, for example: `PayingTooMuchAWSAlarm` and add your email address. 63 | 64 | * You'll have to confirm the subscription link sent to your email before the alarm is activated. 65 | 66 | * Next, add an alarm name, for example `PayingTooMuchAWSAlarm` 67 | 68 | [📹 Video](https://egghead.io/lessons/aws-review-billing-dashboard-and-set-up-a-billing-alarm-to-avoid-paying-too-much-for-aws?pl=use-aws-billing-cost-management-dashboard-to-keep-your-aws-bill-to-minimum-ff0f) tutorial. 69 | 70 | ## Installing AWS CLI 71 | 72 | There are several ways of installing the `aws CLI`. I'm on a macOS computer and installed it using the graphical interface. 73 | 74 | 🤔 [Source](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) 75 | 76 | Verify that `aws` CLI has been installed: 77 | 78 | * `aws --version` 79 | 80 | Now let's start configuring it (have your `.cvs` file with your access keys ready), run: 81 | 82 | * `aws configure` 83 | 84 | * For the region I chose: `eu-central-1` (Frankfurt) since I'm based in Europe. 85 | 86 | 👍 You can check the list of available regions back in your IAM Management Console, by clicking **Global** in your top right corner. 87 | 88 | * For the output format, I left it at default. 89 | 90 | To verify that your settings have been configured successfully run: 91 | 92 | * `aws s3 ls` 93 | 94 | Even if you have no visible output (because you currently don't have any active `s3` buckets), no errors means happy aws! 95 | 96 | To see your credentials run: 97 | 98 | * `cat ~/.aws/credentials` 99 | -------------------------------------------------------------------------------- /01-install-aws-cloud-development-kit-cdk-and-create-a-new-project.md: -------------------------------------------------------------------------------- 1 | # Install AWS Cloud Development Kit (CDK) and create a new project 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-install-aws-cloud-development-kit-cdk-and-create-a-new-project)** 4 | 5 | We'll start by installing the [AWS Cloud Development Kit](https://aws.amazon.com/cdk/). 6 | 7 | * `npm install -g aws-cdk` 8 | 9 | `-g` stands for global (meaning that once installed, this package will be available anywhere on your computer) 10 | 11 | 👍 Throughout the course, Tomasz will use both `yarn` and `npm` package mangers, and it's really up to you to decide which one to use, as both work fine. 12 | 13 | Verify that`cdk` was installed. 14 | 15 | * `cdk --version` 16 | 17 | Initialize a new `cdk` project. 18 | 19 | * `cdk init` 20 | 21 | ```bash 22 | * sample-app: Example CDK Application with some constructs 23 | └─ cdk init sample-app --language=[csharp|fsharp|java|javascript|python|typescript] 24 | ``` 25 | We are going to choose the `sample app`, `typescript` template: 26 | 27 | * `cdk init sample-app --language=typescript` 28 | 29 | This will create a bunch of files with the following directory structure (note that I'm displaying files just one level deep here): 30 | 31 | ``` 32 | . 33 | ├── .git 34 | ├── .gitignore 35 | ├── .npmignore 36 | ├── README.md 37 | ├── bin 38 | ├── cdk.json 39 | ├── jest.config.js 40 | ├── lib 41 | ├── node_modules 42 | ├── package-lock.json 43 | ├── package.json 44 | ├── test 45 | └── tsconfig.json 46 | ``` 47 | 👍 You can run `tree -la 1` to display the tree. -------------------------------------------------------------------------------- /02-build-and-deploy-a-sample-aws-cloud-development-kit-stack-to-aws.md: -------------------------------------------------------------------------------- 1 | # Build and deploy a sample AWS Cloud Development Kit stack to AWS 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-build-and-deploy-a-sample-aws-cloud-development-kit-stack-to-aws)** 4 | 5 | Although many files have been installed when we initialized a new `cdk` project, we'll only touch two of those files (and we'll create some new files too): 6 | 7 | 1. the `.ts` file found in the `bin` directory (`todo-app.ts` for Tomasz). This is the app's entry point (kind of like `index.js` in your standard `reactJS` application) 8 | 9 | 2. the `.ts` file found in `lib` directory (`todo-app-stack.ts` for Tomasz). This is where our stack is defined and where we will write most of our code (Similar to `app.js` in your typical `ReactJS` application). 10 | 11 | 👍 I will refer to the second file as the **stack file**. 12 | 13 | At the top of the stack file, you'll find several imports. 14 | 15 | `import * as sns from '@aws-cdk/aws-sns';` 16 | 17 | This is the core `cdk` library that every stack file needs. We'll be deleting the rest of the imports shortly, mainly: 18 | 19 | * SNS or ([Amazon Simple Notification Service](https://aws.amazon.com/sns)) 20 | 21 | * SQS or ([Amazon Simple Queue Service](https://aws.amazon.com/sqs/)) 22 | 23 | These imports are an example of [constructs](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html). In `aws` constructs are the basic building blocks of AWS CDK apps. A construct can be a single resource, or it can be a higher-level component that has multiple resources. Constructs can be published to `npm` and you can import constructs by other users to your own code. 24 | 25 | We'll use `typescript`, so let's start the `typescript` compiler to watch for any errors. 26 | 27 | * Run `npm run watch` 28 | 29 | 👍 Note, you should have the compiler running every time you work on the `cdk` project (it will save you a lot of time that you would otherwise spend chasing errors/warnings!) 30 | 31 | * Then open **a new terminal window/tab** and run: `cdk diff` 32 | 33 | 👍 Similar to `git diff`, this will give you a preview of you what you'll be deploying. 34 | 35 | 👍 Side note: if you haven't used `aws` before (like me!), you will get this error message: `Unable to resolve AWS account to use. It must be either configured when you define your CDK or through the environment`. 36 | 37 | Don't panic, Tomasz created a video to help you set up, and I've added notes on that in the [00-Intro and Welcome](00-intro-and-welcome.md) section of the notes. 38 | 39 | Running `cdk diff` for the first time will produce a list of things to be deployed. The most important changes can be found under `Resources`. 40 | 41 | ```bash 42 | Resources 43 | [+] AWS::SQS::Queue TodoAppQueue TodoAppQueueF04C191C 44 | [+] AWS::SQS::QueuePolicy TodoAppQueue/Policy TodoAppQueuePolicy77BA4F8B 45 | [+] AWS::SNS::Subscription TodoAppQueue/TodoAppStackTodoAppTopic0382DBE7 TodoAppQueueTodoAppStackTodoAppTopic0382DBE791B1BFB6 46 | [+] AWS::SNS::Topic TodoAppTopic T 47 | ``` 48 | 49 | To deploy run: 50 | 51 | * `cdk deploy` 52 | 53 | 👍 Every time we're making **potentially sensitive changes**, we'll be asked to confirm that we are ready to deploy. Hit `y` to agree. 54 | -------------------------------------------------------------------------------- /03-review-an-aws-cloud-formation-stack-deployed-with-aws-cdk.md: -------------------------------------------------------------------------------- 1 | # Review an AWS CloudFormation stack deployed with AWS CDK 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-review-an-aws-cloudformation-stack-deployed-with-aws-cdk)** 4 | 5 | CDK is built on top of **CloudFormation**. 6 | 7 | But [what is CloudFormation?](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html) 8 | 9 | It's a tool from AWS that allows you to spin up resources effortlessly. You write a template (using `YAML` or `json`) and then AWS does the rest. 10 | 11 | Instead of writing `yaml` or `json`, we'll be using `cdk`, and write our code in `typescript`. Afterward, our code will be transformed into a CloudFormation template and our stack deployed to `aws`. 12 | 13 | To view your current stack got to **AWS Management Console** search for **CloudFormation** and click on **Stacks** in the sidebar on the left. 14 | 15 | 👍 Note that whenever I refer to aws (management) console, I mean the console living on https://aws.amazon.com/console. You will have to be logged in to see your changes. 16 | 17 | 👍 Make sure that you are selecting the right region (the region where your `cdk` app was initialized) as well. 18 | 19 | Stack status should say: `CREATE_COMPLETE` 20 | 21 | You can check out all the resources deployed, under the **Resources** tab. 22 | 23 | Lastly, see all the `yaml` code that we have been spared from writing, by checking out the **CloudFormation** tab. 24 | 25 | If you prefer to visualize your code, click on **View in designer** (you might need to scroll down and zoom-in to see your template). This is particularly useful with a larger infrastructure as it enables an overview of how different pieces are connected. 26 | 27 | ![CloudFormation Trigger Image](https://res.cloudinary.com/dg3gyk0gu/image/upload/v1591637696/transcript-images/03-review-an-aws-cloud-formation-stack-deployed-with-aws-cdk-trigger-image.png) -------------------------------------------------------------------------------- /04-clear-an-initial-aws-cdk-stack-to-start-building-an-app-from-scratch.md: -------------------------------------------------------------------------------- 1 | # Clear an initial AWS CDK stack to start building an app from scratch 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-clear-an-initial-aws-cdk-stack-to-start-building-an-app-from-scratch)** 4 | 5 | Cleaning time! We'll be removing some code generated by the `sample-app` that we don't need. 6 | 7 | Go to `todo-app-stack` and remove all the references to `sns.Topic` and `sqs.Queue`. Remove the unused imports as well. 8 | 9 | Run `cdk diff` to preview your changes (we'll be **destroying** a bunch of resources). 10 | 11 | Then `cdk deploy` to deploy (note this will overwrite your previous deploy). 12 | 13 | Verify your changes in the AWS console. -------------------------------------------------------------------------------- /05-create-and-deploy-a-lambda-function-with-aws-cdk.md: -------------------------------------------------------------------------------- 1 | # Create and deploy a lambda function with AWS CDK 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-create-and-deploy-a-lambda-function-with-aws-cdk)** 4 | 5 | Time to build our serverless backend! 6 | 7 | We'll be writing our first `lambda` function. In order to do that, let's run: 8 | 9 | * `npm install --save @aws-cdk/aws-lambda` 10 | 11 | Since we are using `typescript` we'll also: 12 | 13 | * `npm install --save @types/aws-lambda` 14 | 15 | 👍 We needed to install `aws-lambda` separately because it's not part of the core aws package. See which other constructs/packages are available in CDK [here](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-lambda-readme.html). 16 | 17 | Inside our `todo-app` will create a new directory called `lambda` and inside of it, a `hello.ts` file with the following contents. 18 | 19 | ```ts 20 | // we are going to call this function via APIGatewayEvent which is used for http requests 21 | exports.handler = async function(event: AWSLambda.APIGatewayEvent) { 22 | // this is a neat trick to prettify the console log 23 | console.log("request:", JSON.stringify(event, null, 2)); 24 | 25 | // this is what calling this lambda function will return 26 | return { 27 | statusCode: 200, 28 | headers: { "Content-Type": "text/plain" }, 29 | body: `Hello, egghead friends!` 30 | }; 31 | }; 32 | ``` 33 | 34 | We need to import the lambda function into our stack file: 35 | * `import * as lambda from "@aws-cdk/aws-lambda";` 36 | 37 | Then we'll create an instance of our lambda construct, with three arguments: 38 | 39 | 1. scope (in which the construct is created): usually `this` 40 | 2. `id` 41 | 3. `props` objects (`code`, `handler` and `runtime` are obligatory) 42 | 43 | ```ts 44 | const helloLambda = new lambda.Function(this, "HelloLambda", { 45 | // where our code is located (inside the lambda directory) 46 | code: lambda.Code.fromAsset("lambda"), 47 | // the function executed whenever this lambda function is triggered (the handler function inside hello.ts file) 48 | handler: "hello.handler", 49 | // most recent node 50 | runtime: lambda.Runtime.NODEJS_12_X, 51 | }); 52 | ``` 53 | 54 | Run `cdk diff` to see the two new resources: 55 | 56 | ``` 57 | Resources 58 | [+] AWS::IAM::Role HelloLambda/ServiceRole 59 | [+] AWS::Lambda::Function HelloLambda 60 | ``` 61 | 62 | Then `cdk deploy` 63 | 64 | 👍 Note, if you get the following error (I did): `Error: This stack uses assets, so the toolkit stack must be deployed to the environment`, run `cdk bootstrap` to finish configuring your account and avoid this error in the future. 65 | -------------------------------------------------------------------------------- /06-review-and-execute-a-lambda-function-deployed-with-cdk-in-aws-console.md: -------------------------------------------------------------------------------- 1 | # Review and execute a lambda function deployed with CDK in AWS Console 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-review-and-execute-a-lambda-function-deployed-with-cdk-in-aws-console)** 4 | 5 | Let's go to the [AWS management console](https://aws.amazon.com/console/), search for Cloudformation, click on Stacks, and checkout what we've deployed. 6 | 7 | Under the **Resources** we can see: 8 | * AWS::IAM::Role 9 | * AWS::Lambda::Function 10 | * AWS::CDK::Metadata 11 | 12 | Click on the lambda function id to explore it. You'll be able to use the entire code, which starts with `use strict` and finishes with the sourcemap (because this code was transpiled from `typescript`). 13 | 14 | Further down the page, you'll see **Tags** associated with this function (those were added automatically). 15 | 16 | We currently don't have any **Triggers** so click on **Test** and **Configure test event** to test it manually. Choose [**Api Gateway AWS Proxy**](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html). Name the test then click **Create**. 17 | 18 | Once you click **Test** again the lambda function will be called and you should see the `console.log` with "Hello, egghead friends!" (or your own text). 19 | -------------------------------------------------------------------------------- /07-change-the-properties-of-a-lambda-function-deployed-with-aws-cdk.md: -------------------------------------------------------------------------------- 1 | # Change the properties of a lambda function deployed with AWS CDK 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-change-the-properties-of-a-lambda-function-deployed-with-aws-cdk)** 4 | 5 | Back in the **aws console** we can see that our `lambda` came preconfigured with memory size (128MB) and a timeout of 3 seconds. Let's change that! 6 | 7 | Add the following lines to your stack document: 8 | 9 | ```ts 10 | const helloLambda = new lambda.Function(this, "HelloLambda", { 11 | // to create a 10 second timeout (max is 15 minutes) 12 | timeout: cdk.Duration.seconds(10), 13 | // memory size of 256MB 14 | memorySize: 256, 15 | }); 16 | ``` 17 | ![Lambda Function Image](https://res.cloudinary.com/dg3gyk0gu/image/upload/v1591637696/transcript-images/07-change-the-properties-of-a-lambda-function-deployed-with-aws-cdk-lambda-config-image.png) 18 | 19 | Run `cdk diff` and `cdk deploy` then verify your changes in the `aws console`. -------------------------------------------------------------------------------- /08-attach-an-api-gateway-to-a-lambda-function-deployed-with-aws-cdk.md: -------------------------------------------------------------------------------- 1 | # Attach an API Gateway to a lambda function deployed with AWS CDK 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-attach-an-api-gateway-to-a-lambda-function-deployed-with-aws-cdk)** 4 | 5 | Now let's figure out how to trigger our function! 6 | 7 | We need to attach an [API Gateway](https://aws.amazon.com/api-gateway/) which will allow us to call our `lambda` function from the internet. 8 | 9 | ![API Gateway Illustration](https://res.cloudinary.com/dg3gyk0gu/image/upload/v1592247659/transcript-images/08-attach-an-api-gateway-to-a-lambda-function-deployed-with-aws-cdk-api-gateway.png) 10 | 11 | Run: 12 | * `npm install --save @aws-cdk/aws-apigateway` 13 | 14 | Then import it to the stack file: 15 | `import * as apiGateway from "@aws-cdk/aws-apigateway";` 16 | 17 | Now we will use `apiGateway` to create a REST API for our application. 18 | 19 | Add the following before the closing of the `TodoAppStack` constructor: 20 | 21 | ```ts 22 | new apiGateway.LambdaRestApi(this, "Endpoint", { 23 | handler: helloLambda 24 | }); 25 | ``` 26 | 27 | Let's also update the `body` of our handler inside our `lambda` function to: 28 | 29 | `body: 'Hello, egghead friends! You've hit ${event.path}\n'` 30 | 31 | Run `cdk diff` (a lot of changes will be displayed - this will be the code added by `cdk` due to adding `apiGateway`), then `cdk deploy`. 32 | 33 | Once you've deployed successfully, the terminal will output a URL. Click on it to see your `lambda` function live on the internet. 34 | 35 | You can also check your newly created resources in the `aws` console. If you click on your `lambda` function you'll also see that this function now has a trigger (API Gateway) associated with it. 36 | -------------------------------------------------------------------------------- /09-pass-environment-variables-to-a-lambda-function-deployed-with-aws-cdk.md: -------------------------------------------------------------------------------- 1 | # Pass environment variables to a lambda function deployed with AWS CDK 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-pass-environment-variables-to-a-lambda-function-deployed-with-aws-cdk)** 4 | 5 | Let's pass an environment variable to our `lambda` function. 6 | 7 | We can do that by adding a prop to our `helloLambda` function in the stacks file: 8 | 9 | ```ts 10 | const helloLambda = new lambda.Function(this, "HelloLambda", { 11 | environment: { isProduction: "absolutely not" } 12 | }); 13 | ``` 14 | 15 | Let's `console.log` our variable: 16 | ```ts 17 | console.log("isProduction?", process.env.isProduction); 18 | ``` 19 | 20 | Once you've deployed, you'll be able to see the log. Click on **Test** in the `aws` console and checkout the **Environment variables**. 21 | 22 | ![Environment variable Images](https://res.cloudinary.com/dg3gyk0gu/image/upload/v1591637696/transcript-images/09-pass-environment-variables-to-a-lambda-function-deployed-with-aws-cdk-env-image.png) 23 | -------------------------------------------------------------------------------- /10-run-lambda-functions-built-with-cdk-locally-using-aws-sam.md: -------------------------------------------------------------------------------- 1 | # Run lambda functions built with CDK locally using AWS SAM 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-run-lambda-functions-built-with-cdk-locally-using-aws-sam)** 4 | 5 | Let's learn how to execute our `lambda` function locally (to avoid deploying every time we want to test it). 6 | 7 | We'll be using the AWS Serverless Application Model (SAM) for that. 8 | 9 | Check if you have `SAM` already installed by running: 10 | 11 | * `sam --help`. 12 | 13 | 👍 I don't, so I followed the [instructions for installing it (on mac OS)](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install-mac.html). 14 | 15 | We'll need `docker`, `homebrew` and the `SAM CLI` (`brew tap aws/tap` and `brew install aws-sam-cli`). 16 | 17 | Then, we need to generate a `cloudformattion` template by running: 18 | 19 | * `cdk synth --no-staging > template.yaml` 20 | 21 | Open `template.yaml` and take a moment to appreciate all the code that you didn't need to write (since it's auto-generated by `cloudformattion`). 22 | 23 | Copy your `lambda` function's id, which can be found in several places throughout the `.yaml` file. Mine looks like this: `HelloLambda3D9C82D6`. 24 | 25 | Back in your terminal, invoke the function by running: 26 | 27 | * `sam local invoke HelloLambda3D9C82D6` 28 | 29 | (of course, replace this with your `lambda` id). 30 | 31 | 👍 Make sure you have `docker` running too! 32 | 33 | We won't be able to pass in an event with our existing code, and so `event.path` will result in `undefined`. We can pass it our own events instead! 34 | 35 | In your project root directory create a directory called `sample_events`, inside, create a file called `hello.json` with the following contents: 36 | 37 | ```json 38 | { 39 | "path": "/hello/egghead", 40 | "body": "hello" 41 | } 42 | ``` 43 | 44 | Then run: 45 | * `sam local invoke HelloLambda3D9C82D6 --event=sample_events/hello.json` 46 | 47 | You should get the following output: 48 | 49 | ```json 50 | { 51 | "statusCode": 200, 52 | "headers": {"Content-Type":"text/plain"}, 53 | "body":"Hello, egghead friends! You've hit /hello/egghead\n" 54 | } 55 | ``` 56 | -------------------------------------------------------------------------------- /11-create-and-deploy-an-s3-bucket-with-aws-cdk.md: -------------------------------------------------------------------------------- 1 | # Create and deploy an S3 bucket with AWS CDK 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-create-and-deploy-an-s3-bucket-with-aws-cdk)** 4 | 5 | We'll need storage for our static files (`HTML`, `CSS`, images etc). Let's use [Amazon S3](https://aws.amazon.com/s3/) for that. 6 | 7 | ![S3 Buckets Illustration](https://res.cloudinary.com/dg3gyk0gu/image/upload/v1592247658/transcript-images/11-create-and-deploy-an-s3-bucket-with-aws-cdk-s3-buckets.png) 8 | 9 | We'll create a new `aws` bucket to store our data! 10 | 11 | Run: 12 | 13 | * `npm install --save @aws-cdk/aws-s3` 14 | 15 | Import it into our stack document: 16 | 17 | * `import * as s3 from "@aws-cdk/aws-s3";` 18 | 19 | Let's create a new bucket for storing a logo: 20 | 21 | ```ts 22 | const logoBucket = new s3.Bucket(this, "LogoBucket", { 23 | // we will fill this out later 24 | }); 25 | ``` 26 | 27 | Run: 28 | * `cdk diff` and `cdk deploy`. 29 | 30 | You can find the bucket under `aws` resources (search for `s3`). 31 | -------------------------------------------------------------------------------- /12-make-the-contents-of-an-s3-bucket-deployed-with-cdk-public.md: -------------------------------------------------------------------------------- 1 | # Make the contents of an S3 bucket deployed with CDK public 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-make-the-contents-of-an-s3-bucket-deployed-with-cdk-public)** 4 | 5 | By default, an `s3` bucket is secure and publicly inaccessible. To fix that, we'll have to add a single property to our `LogoBucket`. 6 | 7 | ![Closed Buckets Illustration](https://res.cloudinary.com/dg3gyk0gu/image/upload/v1592247658/transcript-images/12-make-the-contents-of-an-s3-bucket-deployed-with-cdk-public-closed-buckets.png) 8 | 9 | ```ts 10 | const logoBucket = new s3.Bucket(this, "LogoBucket", { 11 | publicReadAccess: true 12 | }); 13 | ``` 14 | 15 | Once deployed, our `s3` links will be available to everyone. 16 | -------------------------------------------------------------------------------- /13-create-an-s3-event-notification-to-trigger-a-lambda-function-on-file-upload.md: -------------------------------------------------------------------------------- 1 | # Create an S3 event notification to trigger a lambda function on file upload 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-create-an-s3-event-notification-to-trigger-a-lambda-function-on-file-upload)** 4 | 5 | Let's trigger our `lambda` function every time we upload a file to our `s3` bucket. 6 | 7 | We'll need to install `s3 notifications`. 8 | 9 | Run: 10 | * `npm install --save @aws-cdk/aws-s3-notifications` 11 | 12 | Import it to our stack file: 13 | 14 | * `import * as s3Notifications from @aws-cdk/aws-s3-notifications;` 15 | 16 | and then: 17 | 18 | ```ts 19 | // attaching a notification to our logo bucket 20 | logoBucket.addEventNotification( 21 | // every time a new file is added to our bucket 22 | s3.EventType.OBJECT_CREATED, 23 | // execute our lambda function 24 | new s3Notifications.LambdaDestination(helloLambda) 25 | ); 26 | ``` 27 | 28 | 👍 Tip: Make sure you have `npm run watch` running in another terminal tab - this will let you know if there are any `typescript` errors. 29 | 30 | In the `aws` console, go to **Services** and search for `s3`. Upload a file to the bucket then check if the `lambda` function was triggered by going back to **Services** and looking for `lambda`. 31 | 32 | 👍 You can see your recently accessed `aws` dashboards in the **History** sidebar on the left. 33 | 34 | In your `lambda` dashboard notice how a new function was added (for me it was: `TodoAppStack-BucketNotificationsHandler050a0587b75-1BQ2LOUD7KPXI`). 35 | 36 | Click on the `HelloLambda` function, then click **Monitoring** and **View logs in CloudWatch**. 37 | 38 | Then click on the latest log and expand the `event` log (it will mention things like `eventVersion`, `eventSource` etc) and look for the information about your recently uploaded image. 39 | 40 | Mine looked like this: 41 | ```json 42 | "object": { 43 | "key": "Screenshot+2020-05-13+at+07.24.34.png", 44 | "size": 19145, 45 | "eTag": "40502d42d31dab5fe8581bd3d7ce0202", 46 | "sequencer": "005EBCD5882BF314F4" 47 | } 48 | ``` 49 | -------------------------------------------------------------------------------- /14-use-a-bucket-deployment-to-upload-a-file-to-s3-when-deploying-a-cdk-stack.md: -------------------------------------------------------------------------------- 1 | # Use a bucket deployment to upload a file to S3 when deploying a CDK stack 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-use-a-bucket-deployment-to-upload-a-file-to-s3-when-deploying-a-cdk-stack)** 4 | 5 | Instead of manually uploading our assets, let's create an `assets` folder in our todo application and upload those assets automatically. 6 | 7 | 👍 We'll be using the `aws-s3-deployment` deployment construct to do that. 8 | 9 | Create an `assets` directory in the root of the project and add a test file to it. 10 | 11 | Run: 12 | 13 | * `npm install --save @aws-cdk/aws-s3-deployment` 14 | 15 | Import it to our todo app: 16 | 17 | `import * as s3Deployment from "@aws-cdk/aws-s3-deployment";` 18 | 19 | Then add the deployment: 20 | ```ts 21 | new s3Deployment.BucketDeployment(this, "DeployLogo", { 22 | destinationBucket: logoBucket, 23 | // an array of sources 24 | sources: [s3Deployment.Source.asset("./assets")] 25 | }); 26 | ``` 27 | 28 | Once we run `cdk deploy` our test file should be safe and sound in our todo `s3` bucket. 29 | -------------------------------------------------------------------------------- /15-create-a-custom-aws-cdk-construct.md: -------------------------------------------------------------------------------- 1 | # Create a custom AWS CDK construct 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-create-a-custom-aws-cdk-construct)** 4 | 5 | Let's start creating a serverless backend for our todo application. 6 | 7 | We're going to create a custom construct, where we are going to put our database and a `lambda` function. 8 | 9 | ![Custom Construct Illustration](https://res.cloudinary.com/dg3gyk0gu/image/upload/v1592247659/transcript-images/15-create-a-custom-aws-cdk-construct-custom-construct-images.png) 10 | 11 | Create a new file next to our stack file (in the `lib` directory), called `todo-backend-ts.` 12 | 13 | Import `aws-cdk/core` then, let's type our custom construct (which is going to look a lot like the `logoBucket` code from our stack file). 14 | 15 | ```ts 16 | export class TodoBackend extends cdk.Construct { 17 | // so we can export it later 18 | public readonly handler: lambda.Function; 19 | 20 | constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { 21 | super(scope, id); 22 | } 23 | } 24 | ``` 25 | 26 | Then import the construct into our main stack app and create an instance of it: 27 | 28 | ```ts 29 | import { TodoBackend } from "./todo-backend"; 30 | 31 | const todoBackend = new TodoBackend(this, "TodoBackend"); 32 | ``` 33 | 34 | Let's cleanup the file a bit: delete `logoBucket`, the `s3Notifications` import, lastly, swap `helloLambda` for `todoBackend.handler`. 35 | -------------------------------------------------------------------------------- /16-create-a-dynamo-db-table-with-aws-cdk.md: -------------------------------------------------------------------------------- 1 | # Create a DynamoDB table with AWS CDK 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-create-a-dynamodb-table-with-aws-cdk)** 4 | 5 | Let's hook our app to a database. We'll be using [DynamoDB](https://aws.amazon.com/dynamodb/), which is a **NoSQL** database. 6 | 7 | ![Storage Illustration](https://res.cloudinary.com/dg3gyk0gu/image/upload/v1592247661/transcript-images/16-create-a-dynamo-db-table-with-aws-cdk-storage-illustration.png) 8 | 9 | 🤔 Side note: What is NoSQL? 10 | 11 | NoSQL allows you to add any kind of data in your database because it is flexible. So we don't have to design a precise schema in advance, we can just start adding our data. 12 | 13 | Run: 14 | 15 | * `npm install --save @aws-cdk/aws-dynamodb` 16 | 17 | Import dynamodb to our backend then create a new dynamo db table. 18 | 19 | ```ts 20 | // save it as a const since we'll use it in a little bit 21 | const todosTable = new dynamodb.Table(this, "TodoTable", { 22 | //a unique key 23 | partitionKey: { name: "id", type: dynamodb.AttributeType.STRING } 24 | }); 25 | ``` 26 | 27 | 👍 Once deployed, you can find the dynamodb resources in the `aws` console (Services - CloudFormattion - TodoAppStack). 28 | 29 | Let's add an item to the table: click on the **Items** tab, then **Create item**. 30 | 31 | Add an `id` then `append` to `String` items: 32 | 33 | ```ts 34 | id: String: 123 35 | todo String: Add DynamoDB 36 | isComplete: true 37 | ``` 38 | 39 | ![Add DynamoDB Image](https://res.cloudinary.com/dg3gyk0gu/image/upload/v1591637697/transcript-images/16-create-a-dynamo-db-table-with-aws-cdk-dynamodb-image.png) 40 | -------------------------------------------------------------------------------- /17-get-all-items-from-a-dynamo-db-table-deployed-with-cdk-using-document-client-api.md: -------------------------------------------------------------------------------- 1 | # Get all items from a DynamoDB table deployed with CDK using DocumentClient API 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-get-all-items-from-a-dynamodb-table-deployed-with-cdk-using-documentclient-api)** 4 | 5 | Let's create a new `lambda` function that is going to be responsible for reading, creating, and deleting data in our database. 6 | 7 | 🤔 A handy [dynamodb cheatsheet](https://github.com/dabit3/dynamodb-documentclient-cheat-sheet). 8 | 9 | 👍 Create `todoHandler.ts` (we can also delete the other `hello` lambda function since we just used it for testing). 10 | 11 | 🤔 The source code is available [here](https://github.com/tlakomy/egghead-aws-cdk-workshop/blob/master/todo-app/lesson_07/lambda/todoHandler.ts). 12 | 13 | ```ts 14 | import AWS = require("aws-sdk"); 15 | // the table name that we get from an env variable 16 | const tableName = process.env.TABLE_NAME || ""; 17 | // for interacting with dynamoDB from JavaScript / nodeJS 18 | const dynamo = new AWS.DynamoDB.DocumentClient(); 19 | 20 | const createResponse = ( 21 | body: string | AWS.DynamoDB.DocumentClient.ItemList, 22 | statusCode = 200 23 | ) => { 24 | return { 25 | statusCode, 26 | body: JSON.stringify(body, null, 2) 27 | }; 28 | }; 29 | // DynamoDB Scan operation scans and returns all of the items in the db 30 | const getAllTodos = async () => { 31 | const scanResult = await dynamo 32 | .scan({ 33 | TableName: tableName 34 | }) 35 | .promise(); 36 | 37 | return scanResult; 38 | }; 39 | // async function that respons to apiGateway events 40 | exports.handler = async function(event: AWSLambda.APIGatewayEvent) { 41 | try { 42 | const { httpMethod, body: requestBody } = event; 43 | // GET request 44 | if (httpMethod === "GET") { 45 | const response = await getAllTodos(); 46 | 47 | return createResponse(response.Items || []); 48 | } 49 | return createResponse( 50 | `We only accept GET requests for now, not ${httpMethod}`, 51 | 500 52 | ); 53 | } catch (error) { 54 | console.log(error); 55 | return createResponse(error, 500); 56 | } 57 | }; 58 | ``` 59 | 60 | We'll have to make some changes to our `todo-backend` file. Let's make a new `lambda` function: 61 | 62 | `import * as lambda from "@aws-cdk/aws-lambda";` 63 | 64 | ```ts 65 | // use this instead of const, you'll say in a moment 66 | this.handler = new lambda.Function(this, "TodoHandler", { 67 | code: lambda.Code.fromAsset("lambda"), 68 | // the name of the method in your code that lambda will call 69 | // our file is called `todoHandler.ts` and it `exports.handler` 70 | handler: "todoHandler.handler", 71 | runtime: lambda.Runtime.NODEJS_12_X, 72 | // we need to pass the name of our table as env variable 73 | environment: { 74 | TABLE_NAME: todosTable.tableName 75 | } 76 | }); 77 | ``` -------------------------------------------------------------------------------- /18-debug-permission-issues-and-allow-a-lambda-function-to-access-data-from-a-dynamo-db-table.md: -------------------------------------------------------------------------------- 1 | # Debug permission issues and allow a lambda function to access data from a DynamoDB table 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-debug-permission-issues-and-allow-a-lambda-function-to-access-data-from-a-dynamodb-table)** 4 | 5 | Let's deploy our changes and test the new `lambda` function. 6 | 7 | A successful deploy will output a url (mine looks like this: 8 | `https://6olvq234234.execute-api.eu-central-1.amazonaws.com/prod/`). 9 | 10 | Unfortunately, if you `curl` that url (or paste it into your web browser), you'll discover the following error: 11 | * `AccessDeniedException` 12 | 13 | To debug this, let's go to the `aws` console and look for our `lambda` function (under resources in Cloudformation). 14 | 15 | Click **Monitoring** and **View Cloud logs**, then click on the latest log stream. You should find an error like this: 16 | * `is not authorized to perform: dynamodb:Scan on resource:` 17 | 18 | 👍 By default, `aws` follows the principle of the least privilege, so we'll have to add some permissions. 19 | 20 | We need this line of code to our `lambda`: 21 | * `todosTable.grantReadWriteData(this.handler);` 22 | 23 | Test if the fix worked, by `curl`-ing the outputted url. It should return your todos. -------------------------------------------------------------------------------- /19-adding-data-to-a-dynamo-db-table-with-put-operation.md: -------------------------------------------------------------------------------- 1 | # Adding data to a DynamoDB table with put operation 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-adding-data-to-a-dynamodb-table-with-put-operation)** 4 | 5 | Let's implement the ability to add todos! 6 | 7 | Start by updating the handler in our lambda, by adding: 8 | 9 | ```ts 10 | try { 11 | const { httpMethod, body: requestBody } = event; 12 | // if GET return todos 13 | if (httpMethod === "GET") { 14 | const response = await getAllTodos(); 15 | 16 | return createResponse(response.Items || []); 17 | } 18 | if (!requestBody) { 19 | return createResponse("Missing request body", 500); 20 | } 21 | 22 | // parsing the data we sent to the server 23 | const data = JSON.parse(requestBody); 24 | // if POST add a todo 25 | if (httpMethod === "POST") { 26 | const todo = await addTodoItem(data); 27 | return todo 28 | ? createResponse(`${todo} added to the database`) 29 | : createResponse("Todo is missing", 500); 30 | } 31 | // if DELETE, delete todo (we'll imlement that in the next lesson) 32 | if (httpMethod === "DELETE") { 33 | const id = await deleteTodoItem(data); 34 | return id 35 | ? createResponse( 36 | `Todo item with an id of ${id} deleted from the database` 37 | ) 38 | : createResponse("ID is missing", 500); 39 | } 40 | 41 | return createResponse( 42 | `We only accept GET, POST, OPTIONS and DELETE, not ${httpMethod}`, 43 | 500 44 | ); 45 | } catch (error) { 46 | console.log(error); 47 | return createResponse(error, 500); 48 | } 49 | ``` 50 | 51 | 🤔 The source code is available [here](https://github.com/tlakomy/egghead-aws-cdk-workshop/blob/master/todo-app/lesson_08/lambda/todoHandler.ts). 52 | 53 | Now let's write the function for adding the todos (head here for the [dynamoDB cheatsheet](https://github.com/dabit3/dynamodb-documentclient-cheat-sheet)). 54 | 55 | We'll be using the `PUT` method, which either adds an item or replaces the item if the item already exists. 56 | 57 | ```ts 58 | const addTodoItem = async (data: { todo: string; id: string }) => { 59 | const { id, todo } = data; 60 | if (todo && todo !== "") { 61 | await dynamo 62 | .put({ 63 | // params object with two properties (TableName is our env variable) 64 | TableName: tableName, 65 | Item: { 66 | id: "this_is_a_new_id", 67 | todo 68 | } 69 | }) 70 | .promise(); 71 | } 72 | return todo; 73 | }; 74 | ``` 75 | 76 | 👍 Let's deploy and test! 77 | 78 | You'll need a REST client (like [Insomnia](https://insomnia.rest/) or [Postman](https://www.postman.com/product/api-client/)) to test the `POST` request and of course, your app's endpoint. 79 | 80 | For a `POST` request set the `body` to `JSON` (in Postman that means setting `Content-Type:application/json` in `Headers`). 81 | -------------------------------------------------------------------------------- /20-delete-an-item-from-a-dynamo-db-table-with-delete-operation.md: -------------------------------------------------------------------------------- 1 | # Delete an item from a DynamoDB table with delete operation 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-delete-an-item-from-a-dynamodb-table-with-delete-operation)** 4 | 5 | Let's delete a todo! 6 | 7 | ```ts 8 | const deleteTodoItem = async (data: { id: string }) => { 9 | const { id } = data; 10 | 11 | if (id && id !== "") { 12 | await dynamo 13 | .delete({ 14 | TableName: tableName, 15 | Key: { 16 | // each todo needs a unique id 17 | id 18 | } 19 | }) 20 | .promise(); 21 | } 22 | 23 | return id; 24 | }; 25 | ``` 26 | 27 | Let's test this by sending a `DELETE` request: 28 | ```JSON 29 | { 30 | "id": "this_is_a_new_id" 31 | } 32 | ``` 33 | 34 | We should get a response like this: `"Todo item with an id of this_is_a_new_id deleted from the database"`. 35 | 36 | 👍 Validate that the todo item was indeed deleted with a new `GET` request. 37 | -------------------------------------------------------------------------------- /21-add-external-dependencies-to-an-aws-lambda-function-deployed-with-cdk.md: -------------------------------------------------------------------------------- 1 | # Add external dependencies to an AWS Lambda function deployed with CDK 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-add-external-dependencies-to-an-aws-lambda-function-deployed-with-cdk)** 4 | 5 | Let's figure out how to add unique, random `ids` (a.k.a. the Partition Key) to our todos. 6 | 7 | 👍 We'll add the `uuid` dependency to our `lambda` function. 8 | 9 | Navigate to the `lambda` directory and run: 10 | 11 | * `npm init -y` 12 | 13 | This will initialize a new `package.json`. Then run: 14 | 15 | * `yarn add uuid` 16 | * `yarn add @types/uuid` 17 | 18 | (since we are using `typescript`) 19 | 20 | Then in our `lambda` function, import `uuid`: 21 | 22 | * `import { v4 as uuid} from "uuid"` 23 | 24 | Now change the `addTodoItem`: 25 | ```ts 26 | Item: { 27 | // use either an id provided through the UI, or get a randomly generated id with uuid 28 | id: id || uuid(), 29 | todo 30 | } 31 | ``` 32 | 33 | 👍 Test that `uuid` is working by adding a new todo via a REST client. 34 | -------------------------------------------------------------------------------- /22-connect-react-app-to-a-serverless-backend-deployed-with-cdk-and-fix-cors-issues.md: -------------------------------------------------------------------------------- 1 | # Connect React app to a serverless backend deployed with CDK and fix CORS issues 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-connect-react-app-to-a-serverless-backend-deployed-with-cdk-and-fix-cors-issues)** 4 | 5 | Let's connect our backend to a frontend react application. Download the `frontend` directory from [here](https://github.com/tlakomy/egghead-aws-cdk-workshop). 6 | 7 | Your root directory should now look like this: 8 | ``` 9 | . 10 | ├── frontend 11 | └── todoApp 12 | ``` 13 | 14 | Go to `frontend` and install all dependencies by running: 15 | 16 | * `yarn install`. 17 | 18 | And then: 19 | 20 | * `yarn start` 21 | 22 | Unfortunately, you'll get the following error: 23 | 24 | * `failed to load resource: net::ERR_NAME_NOT_RESOLVED`. 25 | 26 | To fix the error, go to the `app.tsx` in the frontend application. 27 | 28 | There's an issue with the `APIendpoint` which we should be passing as an `env` variable `REACT_APP_TODO_ENDPOINT` (in the `.env` file). Replace the dummy url provided with your own (you can copy it from the REST Client). 29 | 30 | 👍 Restart the app and try again. 31 | 32 | Now we will encounter a `CORS` issue. To fix it modify the `createReponse` function in your `lambda` file so that it includes the two `headers` properties and returns this: 33 | 34 | ```ts 35 | return { 36 | statusCode, 37 | headers: { 38 | // this API can be accessed from all origins 39 | "Access-Control-Allow-Origin": "*", 40 | // and will allow for all of these methods 41 | // OPTIONS is a pre-flight method and is sent before the actual method `GET`, `POST`, `DELETE` 42 | "Access-Control-Allow-Methods": "OPTIONS,GET,POST,DELETE" 43 | }, 44 | body: JSON.stringify(body, null, 2) 45 | }; 46 | ``` 47 | 48 | 🤔 [More about the `OPTIONS` method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS). 49 | 50 | Finally, add this to the handler (in the same file): 51 | ```ts 52 | if (httpMethod === "OPTIONS") { 53 | return createResponse("ok"); 54 | } 55 | ``` 56 | 57 | 👍 Deploy, and now your frontend app should be working. 58 | -------------------------------------------------------------------------------- /23-add-a-custom-cloud-formation-stack-output-with-cdk.md: -------------------------------------------------------------------------------- 1 | # Add a custom CloudFormation stack output with CDK 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-add-a-custom-cloudformation-stack-output-with-cdk)** 4 | 5 | Let's fix the missing logo at the bottom of our todo application. We need to tell our frontend application to source it from our `s3` `logoBucket`. 6 | 7 | Instead of manually searching for the logo url in our `aws` console (not a true hacker move!), we can output the url in our terminal with each deployment. 8 | 9 | To do that, let's modify the `output` in our stack file by adding this: 10 | ```ts 11 | new cdk.CfnOutput(this, "LogoPath", { 12 | // add the name of your bucket and your file (in the assets folder) 13 | value: `https://${logoBucket.bucketDomainName}/testFile.png` 14 | }); 15 | ``` 16 | 17 | 👍 Once you deploy, you should see the logo path in the output section. 18 | 19 | Now go to the frontend application and add this `url` as the logo `src` (in `app.tsx`). 20 | -------------------------------------------------------------------------------- /24-deploy-a-static-website-to-s3-with-aws-cdk.md: -------------------------------------------------------------------------------- 1 | # Deploy a static website to S3 with AWS CDK 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-deploy-a-static-website-to-s3-with-aws-cdk)** 4 | 5 | Let's deploy our frontend app (that currently lives on `localhost`) to the Internet. 6 | 7 | First, let's `build` the app! Go to `frontend` directory and run: 8 | 9 | * `yarn run build` 10 | 11 | We'll be using a new `s3` bucket to host our frontend app! Add the new bucket to the stack file: 12 | 13 | ```ts 14 | const websiteBucket = new s3.Bucket(this, "WebsiteBucket", { 15 | // so that it's publicly available 16 | publicReadAccess: true, 17 | // the index document 18 | websiteIndexDocument: "index.html" 19 | }); 20 | ``` 21 | Instead of copying the contents of the `build` folder manually, let's deploy it automatically by adding this: 22 | 23 | ```ts 24 | new s3Deployment.BucketDeployment(this, "DeployWebsite", { 25 | destinationBucket: websiteBucket, 26 | // path to our build directory 27 | sources: [s3Deployment.Source.asset("../frontend/build")] 28 | }); 29 | ``` 30 | 31 | Lastly, just like with the logo url, let's output the website url. 32 | 33 | ```ts 34 | new cdk.CfnOutput(this, "WebsiteUrl", { 35 | value: websiteBucket.bucketWebsiteUrl 36 | }); 37 | ``` -------------------------------------------------------------------------------- /25-deploy-a-site-with-https-support-behind-a-cdn-with-cdk.md: -------------------------------------------------------------------------------- 1 | # Deploy a site with HTTPS support behind a CDN with CDK 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-deploy-a-site-with-https-support-behind-a-cdn-with-cdk)** 4 | 5 | We want our website to be secure and served on `https` (and not on `http`) - let's fix that. 6 | 7 | Also, in the previous lesson, we had to type out the three steps for deploying our frontend: 8 | 9 | * Creating a bucket 10 | * Creating a bucket deployment 11 | * Creating a CloudFormation output 12 | 13 | We can solve both things by using [CDK-SPA-Deploy](https://github.com/nideveloper/CDK-SPA-Deploy)! It can be used to deploy an SPA (Single Page Application), written in `reactJS` (or Angular/Vue) to `aws` behind SSL (meaning `https`) on CloudFront. 14 | 15 | To add it, run: 16 | * `npm install --save cdk-spa-deploy` 17 | 18 | 🤔 [Cloudfront](https://aws.amazon.com/cloudfront/) is Amazon's CDN (Content Delivery Network). 19 | 20 | ![CDN Illustration](https://res.cloudinary.com/dg3gyk0gu/image/upload/v1592247660/transcript-images/25-deploy-a-site-with-https-support-behind-a-cdn-with-cdk-cdn.png) 21 | 22 | Import it to the stack file: 23 | 24 | * `import { SPADeploy } from "cdk-spa-deploy";` 25 | 26 | Then comment out (or remove) the three sections that we wrote in the last time lesson and replace them with: 27 | 28 | ```ts 29 | new SPADeploy(this, "WebsiteDeployment").createSiteWithCloudfront({ 30 | indexDoc: "index.html", 31 | websiteFolder: "../frontend/build" 32 | }); 33 | ``` 34 | 35 | 🤔 You can check out the source code [here](https://github.com/tlakomy/egghead-aws-cdk-workshop/blob/master/todo-app/lesson_13/lib/todo-app-stack.ts). -------------------------------------------------------------------------------- /26-destroy-an-aws-cdk-stack.md: -------------------------------------------------------------------------------- 1 | # Destroy an AWS CDK stack 2 | 3 | **[📹 Video](https://egghead.io/lessons/aws-destroy-an-aws-cdk-stack)** 4 | 5 | If at some point you want to delete your app (along with all of its resources), you just need to run: 6 | 7 | * `cdk destroy`. 8 | 9 | The only thing that won't get deleted is the `s3` `LogoBucket` which you can delete manually. 10 | 11 | 👍 And if you want to redeploy the app again in the future (assuming you didn't delete the code on your computer!), just run `cdk deploy` and your app will be live again. 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

DEPRECATED :warning: This notes repo has been moved to eggheadio/notes!

2 | 3 |

Build an App with the AWS Cloud Development Kit

4 | 5 |

6 | 7 | 8 | [![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors-) 9 | 10 | 11 | ## About 🔍 12 | 13 | This repo contains notes from [Tomasz Łakomy](https://twitter.com/tlakomy)'s Egghead course [Build an App with the AWS Cloud Development Kit](https://egghead.io/courses/build-an-app-with-the-aws-cloud-development-kit?af=6p5abz). 14 | 15 | These notes contain the same structure as the transcriptions, along with additional rewrites, links to resources, and personal takes on the lesson. Feel free to submit additions to these notes, but please don't remove anything (unless we messed up or misunderstood something). 16 | 17 | Generally, there is one document for each lesson in the course. If there are related lessons, the notes will be in the same document. 18 | 19 | ## Course Objective 💪 20 | 21 | You've probably already heard of cloud computing, `aws`, `lambda` functions, `s3` buckets, but maybe have no idea what those things are. Good news! This course serve as an introduction to all of these things and more! 22 | 23 | You'll learn how to deploy a `cdk` template, write your first `lambda` function, initialize a new `s3` bucket to store your assets, save things in a NoSQL database called `dynamoDB`, connect a `react` application to your backend and deploy all of it to a CDN! 24 | 25 | By the end of the course you'll not only have a good understanding of (some of) `aws` features, you'll also have a working application deployed live on the internet. 26 | 27 | ## AWS CDK Project 🎓 28 | 29 | After completing the course and absorbing all of this knowledge, the best way to solidify it is by using it! 30 | 31 | You can find a challenge written up for you to test your new AWS knowledge in the [Course Project](./course-project/README.md) folder. We've given you a scenario for you to implement a feature through AWS services. 32 | 33 | You'll notice that there is a [community solutions](./course-project/community-solutions.md) folder within the Course Project section. We encourage you to submit a PR and add your solution! 34 | 35 | ## Prerequisites ✅ 36 | During this course we're going to talk quite a bit about AWS Lambda, DynamoDB and we're going to play with AWS SAM a bit. This is not required but I think you will get more out of the course if you take a look at those resources first (don't worry - I will be explaining those concepts during the course as well): 37 | 38 | [🤔 Tomasz's notes](https://gist.github.com/tlakomy/f1312ec1fd092ece75a0f72403235fc8) and [workshop docs](https://github.com/tlakomy/egghead-aws-cdk-workshop/tree/master/docs) 39 | 40 | | Learn AWS Lambda from scratch | Learn AWS Serverless Application Model (AWS SAM) from scratch | Learn DynamoDB from scratch | Intro to DynamoDB by [Chris Biscardi](https://egghead.io/instructors/chris-biscardi?af=6p5abz) | 41 | |-------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------| 42 | | [📹 Collection](https://egghead.io/playlists/learn-aws-lambda-from-scratch-d29d?af=6p5abz) | [📹 Collection](https://egghead.io/playlists/learn-aws-serverless-application-model-aws-sam-framework-from-scratch-baf9?af=6p5abz) | [📹 Collection](https://egghead.io/playlists/learn-aws-dynamodb-from-scratch-21c3?af=6p5abz) | [📹 Collection](https://egghead.io/playlists/learn-aws-dynamodb-from-scratch-21c3?af=6p5abz) | 43 | | [🤔 Notes](https://github.com/theianjones/egghead.io_learn_aws_lambda_from_scratch) | [🤔 Notes](https://github.com/eggheadio-projects/build-serverless-applications-with-aws-sam) | [🤔 Notes](https://github.com/eggheadio-projects/learn-aws-dynamodb-from-scratch) | [🤔 Notes](https://github.com/eggheadio-projects/intro-to-dynamodb) | 44 | 45 | ## Who is Tomasz Łakomy? 👨‍💻 46 | 47 | Senior Frontend Engineer at OLX Group. His interests include React, AWS, testing, Svelte, VR, app performance and... jQuery, which he still thinks is the best library ever. 48 | 49 | [Other Egghead content](https://egghead.io/instructors/tomasz-lakomy) created by Tomasz. 50 | 51 | ## Table of Contents 📜 52 | 53 | - [00-Intro and Welcome](00-intro-and-welcome.md) 54 | - [01-Install AWS Cloud Development Kit (CDK) and create a new project](01-install-aws-cloud-development-kit-cdk-and-create-a-new-project.md) 55 | - [02-Build and deploy a sample AWS Cloud Development Kit stack to AWS](02-build-and-deploy-a-sample-aws-cloud-development-kit-stack-to-aws.md) 56 | - [03-Review an AWS CloudFormation stack deployed with AWS CDK](03-review-an-aws-cloud-formation-stack-deployed-with-aws-cdk.md) 57 | - [04-Clear an initial AWS CDK stack to start building an app from scratch](04-clear-an-initial-aws-cdk-stack-to-start-building-an-app-from-scratch.md) 58 | - [05-Create and deploy a lambda function with AWS CDK](05-create-and-deploy-a-lambda-function-with-aws-cdk.md) 59 | - [06-Review and execute a lambda function deployed with CDK in AWS Console](06-review-and-execute-a-lambda-function-deployed-with-cdk-in-aws-console.md) 60 | - [07-Change the properties of a lambda function deployed with AWS CDK](07-change-the-properties-of-a-lambda-function-deployed-with-aws-cdk.md) 61 | - [08-Attach an API Gateway to a lambda function deployed with AWS CDK](08-attach-an-api-gateway-to-a-lambda-function-deployed-with-aws-cdk.md) 62 | - [09-Pass environment variables to a lambda function deployed with AWS CDK](09-pass-environment-variables-to-a-lambda-function-deployed-with-aws-cdk.md) 63 | - [10-Run lambda functions built with CDK locally using AWS SAM](10-run-lambda-functions-built-with-cdk-locally-using-aws-sam.md) 64 | - [11-Create and deploy an S3 bucket with AWS CDK](11-create-and-deploy-an-s3-bucket-with-aws-cdk.md) 65 | - [12-Make the contents of an S3 bucket deployed with CDK public](12-make-the-contents-of-an-s3-bucket-deployed-with-cdk-public.md) 66 | - [13-Create an S3 event notification to trigger a lambda function on file upload](13-create-an-s3-event-notification-to-trigger-a-lambda-function-on-file-upload.md) 67 | - [14-Use a bucket deployment to upload a file to S3 when deploying a CDK stack](14-use-a-bucket-deployment-to-upload-a-file-to-s3-when-deploying-a-cdk-stack.md) 68 | - [15-Create a custom AWS CDK construct](15-create-a-custom-aws-cdk-construct.md) 69 | - [16-Create a DynamoDB table with AWS CDK](16-create-a-dynamo-db-table-with-aws-cdk.md) 70 | - [17-Get all items from a DynamoDB table deployed with CDK using DocumentClient API](17-get-all-items-from-a-dynamo-db-table-deployed-with-cdk-using-document-client-api.md) 71 | - [18-Debug permission issues and allow a lambda function to access data from a DynamoDB table](18-debug-permission-issues-and-allow-a-lambda-function-to-access-data-from-a-dynamo-db-table.md) 72 | - [19-Adding data to a DynamoDB table with put operation](19-adding-data-to-a-dynamo-db-table-with-put-operation.md) 73 | - [20-Delete an item from a DynamoDB table with delete operation](20-delete-an-item-from-a-dynamo-db-table-with-delete-operation.md) 74 | - [21-Add external dependencies to an AWS Lambda function deployed with CDK](21-add-external-dependencies-to-an-aws-lambda-function-deployed-with-cdk.md) 75 | - [22-Connect React app to a serverless backend deployed with CDK and fix CORS issues](22-connect-react-app-to-a-serverless-backend-deployed-with-cdk-and-fix-cors-issues.md) 76 | - [23-Add a custom CloudFormation stack output with CDK](23-add-a-custom-cloud-formation-stack-output-with-cdk.md) 77 | - [24-Deploy a static website to S3 with AWS CDK](24-deploy-a-static-website-to-s3-with-aws-cdk.md) 78 | - [25-Deploy a site with HTTPS support behind a CDN with CDK](25-deploy-a-site-with-https-support-behind-a-cdn-with-cdk.md) 79 | - [26-Destroy an AWS CDK stack](26-destroy-an-aws-cdk-stack.md) 80 | 81 | ## Emoji Legend 🧠 82 | 83 | | emoji| explanation | 84 | | -----|:------------------------:| 85 | | 📹 | links to the course video| 86 | | 💻 | course repository | 87 | | ⌨️ | keyboard shortcut | 88 | | 🤔 | additional resources | 89 | | 👍 | good practice | 90 | 91 | 92 | ## Contributors ✨ 93 | 94 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 |

Lauro Silva

👀

edieblu

🖋 📓

Appleton

🎨

Lucas Minter

👀

Kamil Khadeyev

🎨

Creeland A. Provinsal

🖋

Zac Jones

🖋

William Johnson

👀

Ian Jones

📓

Pixel

🖋

Zakos

🐛

Ben

🖋

Pierre Grimaud

🖋
117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /course-project/README.md: -------------------------------------------------------------------------------- 1 | # The Project 2 | 3 | ## The Brief 4 | 5 | Our client wants to build up a subscriber list to market their new product. The client is paying for AWS and wants us to use it for this project. You are a full-stack engineer and your project manager has tasked you with finding a way to store all the subscriber's emails and creating a way to capture subscriber emails. 6 | 7 | The frontend team has come up with a couple of prototypes for the frontend form. You could either wire up one of their prototypes or roll your own! 8 | 9 | Your project manager recommends you use the command `cdk init` to save time. AWS CDK converts into JSON/YAML so the language you implement this feature in is completely up to you! If you need assistance with setting up the project the backend team has a suggested configuration for this type of project. You can browse or copy the [Backend Starter](https://github.com/Creeland/AWS-CDK-Backend-Starter) that has the set up done for you if you don't want to start completely from scratch. 10 | 11 | 12 | ## Requirements: 13 | 14 | - [ ] Wire up a form for users to input their email 15 | - [ ] Handle user input with AWS Lambda 16 | - [ ] Store that email on AWS using DynamoDB 17 | 18 | ### Stretch Goals 19 | - [ ] Display emails on the page 20 | - [ ] Delete emails from the list 21 | - [ ] Add the company logo to the form 22 | 23 | ## Project Steps 24 | 25 | 1. Create a DynamoDB table inside your Backend Construct ([lesson 16](https://github.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/blob/master/16-create-a-dynamo-db-table-with-aws-cdk.md)) 26 | 27 | 2. Write method for adding Emails to DynamoDB in Lambda function ([lesson 19](https://github.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/blob/master/19-adding-data-to-a-dynamo-db-table-with-put-operation.md)) 28 | 29 | 3. In the lambda function, call your "add email" method and create a response whenever there is an HTTP POST request ([lesson 19](https://github.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/blob/master/19-adding-data-to-a-dynamo-db-table-with-put-operation.md)) 30 | 31 | 3. Connect your lambda function to your backend ([lesson 17](https://github.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/blob/master/17-get-all-items-from-a-dynamo-db-table-deployed-with-cdk-using-document-client-api.md)) 32 | 33 | 4. Create an API gateway for your lambda function ([lesson 08](https://github.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/blob/master/08-attach-an-api-gateway-to-a-lambda-function-deployed-with-aws-cdk.md)) 34 | 35 | 5. Create a frontend that takes user input and POSTs to your AWS endpoint ([lesson 22](https://github.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/blob/master/22-connect-react-app-to-a-serverless-backend-deployed-with-cdk-and-fix-cors-issues.md)) 36 | 37 | 6. Add CORS headers to createResponse method in lambda function ([lesson 22](https://github.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/blob/master/22-connect-react-app-to-a-serverless-backend-deployed-with-cdk-and-fix-cors-issues.md)) 38 | 39 | 7. Deploy your front end to AWS ([lesson 24](https://github.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/blob/master/24-deploy-a-static-website-to-s3-with-aws-cdk.md)) 40 | 41 | ## Form Prototypes 42 | 43 | - [React form](https://github.com/zacjones93/AWS-CDK-React-Frontend/tree/master) 44 | - [Vue form](https://github.com/Creeland/AWS-CDK-Vue-Frontend) 45 | 46 | ## Backend 47 | 48 | - [Backend Starter](https://github.com/Creeland/AWS-CDK-Backend-Starter) 49 | -------------------------------------------------------------------------------- /course-project/community-solutions.md: -------------------------------------------------------------------------------- 1 | # Community Solutions 2 | 3 | - ⚛️ [React form powered by AWS](https://github.com/zacjones93/aws-cdk-performance-task) from zacjones93 -------------------------------------------------------------------------------- /images/03-review-an-aws-cloud-formation-stack-deployed-with-aws-cdk-trigger-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/b2b3feecf0d86665c28548ffd24a741b2987c585/images/03-review-an-aws-cloud-formation-stack-deployed-with-aws-cdk-trigger-image.png -------------------------------------------------------------------------------- /images/07-change-the-properties-of-a-lambda-function-deployed-with-aws-cdk-lambda-config-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/b2b3feecf0d86665c28548ffd24a741b2987c585/images/07-change-the-properties-of-a-lambda-function-deployed-with-aws-cdk-lambda-config-image.png -------------------------------------------------------------------------------- /images/08-attach-an-api-gateway-to-a-lambda-function-deployed-with-aws-cdk-api-gateway.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/b2b3feecf0d86665c28548ffd24a741b2987c585/images/08-attach-an-api-gateway-to-a-lambda-function-deployed-with-aws-cdk-api-gateway.png -------------------------------------------------------------------------------- /images/09-pass-environment-variables-to-a-lambda-function-deployed-with-aws-cdk-env-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/b2b3feecf0d86665c28548ffd24a741b2987c585/images/09-pass-environment-variables-to-a-lambda-function-deployed-with-aws-cdk-env-image.png -------------------------------------------------------------------------------- /images/11-create-and-deploy-an-s3-bucket-with-aws-cdk-s3-buckets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/b2b3feecf0d86665c28548ffd24a741b2987c585/images/11-create-and-deploy-an-s3-bucket-with-aws-cdk-s3-buckets.png -------------------------------------------------------------------------------- /images/12-make-the-contents-of-an-s3-bucket-deployed-with-cdk-public-closed-buckets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/b2b3feecf0d86665c28548ffd24a741b2987c585/images/12-make-the-contents-of-an-s3-bucket-deployed-with-cdk-public-closed-buckets.png -------------------------------------------------------------------------------- /images/15-create-a-custom-aws-cdk-construct-custom-construct-images.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/b2b3feecf0d86665c28548ffd24a741b2987c585/images/15-create-a-custom-aws-cdk-construct-custom-construct-images.png -------------------------------------------------------------------------------- /images/16-create-a-dynamo-db-table-with-aws-cdk-dynamodb-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/b2b3feecf0d86665c28548ffd24a741b2987c585/images/16-create-a-dynamo-db-table-with-aws-cdk-dynamodb-image.png -------------------------------------------------------------------------------- /images/16-create-a-dynamo-db-table-with-aws-cdk-storage-illustration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/b2b3feecf0d86665c28548ffd24a741b2987c585/images/16-create-a-dynamo-db-table-with-aws-cdk-storage-illustration.png -------------------------------------------------------------------------------- /images/25-deploy-a-site-with-https-support-behind-a-cdn-with-cdk-cdn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eggheadio-projects/build-an-app-with-the-AWS-cloud-development-kit-notes/b2b3feecf0d86665c28548ffd24a741b2987c585/images/25-deploy-a-site-with-https-support-behind-a-cdn-with-cdk-cdn.png --------------------------------------------------------------------------------