Skip to content

Commit

Permalink
ART: Lambda function how tos
Browse files Browse the repository at this point in the history
  • Loading branch information
rehanhaider committed Nov 5, 2023
1 parent 766582a commit 9fe64e0
Show file tree
Hide file tree
Showing 8 changed files with 604 additions and 5 deletions.
4 changes: 2 additions & 2 deletions content/articles/99999981-aws-cloud-development-kit.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,13 @@ class CdkTutorialStack(cdk.Stack):
"cdk-tutorial",
code=aws_lambda.Code.from_asset("lambda"),
handler="index.main",
runtime=aws_lambda.Runtime.PYTHON_3_8,
runtime=aws_lambda.Runtime.PYTHON_3_10,
layers=[self.create_dependencies_layer(self.stack_name, "lambda/index")],
)
```
Here we use `code` variable to import our code from `lambda` folder, then define Lambda handler to be `main()` method under `index.py` file by using `handler="index.main"`.

We also define the runtime to be Python 3.8 and a layer that is explained later.
We also define the runtime to be Python 3.10 and a layer that is explained later.

## Define EventBridge Schedules and Lambda access permission
Add the below code under where we defined lambda function
Expand Down
211 changes: 211 additions & 0 deletions content/aws/50001000-cdk-fn-create-lambda.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
Title: How to create a lambda function using AWS CDK in Python
Date: 2023-11-05
Category: AWS Academy
Series: AWS CDK
series_index: 1000
Tags: aws, cdk, python
Author: Rehan Haider
Summary: A complete guide to creating a lambda function using AWS CDK
Keywords: lambda, cdk


The easiest way to create a lambda function using AWS CDK is to use the `Function` construct from the `aws_lambda` module. Let's see how to use it.

## Create a simple lambda function

```python
# filename: cdk_app/lambda_stack.py

from aws_cdk import (
Stack,
aws_lambda as _lambda,
)

from constructs import Construct


class LambdaStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)

inline_code = """
def handler(event, context):
return {
"statusCode": 200,
"body": "Hello from Lambda!"
}
"""
# 👆🏽 formatting & indentation is not a mistake

my_lambda = _lambda.Function(
self,
id="MyLambda",
runtime=_lambda.Runtime.PYTHON_3_10,
handler="index.handler",
code=_lambda.Code.from_inline(inline_code),
)

```

You can create the app by modifying the `app.py` file as follows:

```python
# filename: app.py

import aws_cdk as cdk
from cdk_app.lambda_stack import LambdaStack

app = cdk.App()

lambda_stack = LambdaStack(app, "LambdaStack")

app.synth()
```

To deploy, run `cdk deploy`.

Once deployed, you can go to the AWS Console and check the lambda function. You should see the following:

![Lambda inline function]({static}/images/aws/50001000-01-fn-inline-code.png)

### What's happening here?

We used what is known as an **inline code** to create the lambda function. Effectively, the code we want to execute is passed as a string to the `code` property of the `Function` construct.

The `Function` construct takes the following parameters:

- `scope`: The scope in which the construct is created. In our case, it is the `LambdaStack` class.
- `id`: The ID of the construct. This ID is used within CDK to uniquely identify the construct. It is also used as the logical ID in CloudFormation templates.
- `runtime`: The runtime environment for the lambda function. In our case, it is Python 3.10. Other versions of Python are also supported. You can also use other runtimes such as Node.js, Java, Go, etc.
- `handler`: The name of the handler function. In our case, it is `index.handler`. This means that the `handler` function is defined in the `index.py` file.
- `code`: The code to execute. In our case, it is the `inline_code` variable.


But using inline code is not the best way to create a lambda function. It is fine for simple demonstrations, but for anything more complex, you should use a file or a Docker image. Let's see how to do that.


## Create a lambda function from a file

To create a lambda function from a file, you need to use the `Code.from_asset` method. This method takes the path to the file as an argument.

Now one important point, the lambda code needs to be in its own directory. So, you need to create a directory and put the lambda code in that directory.

E.g. in our case, we will create a `cdk_app/lambda` directory and create a file named `index.py` in that directory. The contents of the file will be as follows:

```python
# filename: cdk_app/lambda/index.py

def handler(event, context):
return {
"statusCode": 200,
"body": "Hello from Lambda!",
}
```

Now, we can create the lambda function as follows:

```python
# filename: cdk_app/lambda_stack.py

from aws_cdk import (
Stack,
aws_lambda as _lambda,
)

from constructs import Construct


class LambdaStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)

my_lambda = _lambda.Function(
self,
id="MyLambda",
runtime=_lambda.Runtime.PYTHON_3_10,
handler="index.handler",
code=_lambda.Code.from_asset("cdk_app/lambda"),
)
```

Notice that we have used the `Code.from_asset` method to create the lambda function. We have passed the path to the `lambda` directory as an argument to the method.

Now, when you run `cdk deploy`, you will see that the lambda function is created from the `index.py` file.

## Set environment variables

You can set environment variables for the lambda function by using the `environment` property of the `Function` construct.

```python
# filename: cdk_app/lambda_stack.py

from aws_cdk import (
Stack,
aws_lambda as _lambda,
)

from constructs import Construct


class LambdaStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)

my_lambda = _lambda.Function(
self,
id="MyLambda",
runtime=_lambda.Runtime.PYTHON_3_10,
handler="index.handler",
code=_lambda.Code.from_asset("cdk_app/lambda"),
# 👇🏽 set environment variables
environment={
"ENVIRONMENT": "PROD",
},
)
```

## Set memory size and timeout

By default lambda provide 128 MB of memory and 3 seconds of timeout. That means if your lambda function takes more than 3 seconds to execute, it will timeout.

If your lambda function requires more memory or more time, you can set the `memory_size` and `timeout` properties of the `Function` construct.


```python
# filename: cdk_app/lambda_stack.py

from aws_cdk import (
Stack,
aws_lambda as _lambda,
Duration,
)

from constructs import Construct


class LambdaStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)

my_lambda = _lambda.Function(
self,
id="MyLambda",
runtime=_lambda.Runtime.PYTHON_3_10,
handler="index.handler",
code=_lambda.Code.from_asset("cdk_app/lambda"),
# 👇🏽 set memory size and timeout
memory_size=256,
timeout=Duration.seconds(10),
)
```


## Additional resources for lambda functions

Or learn some advanced methods on how to create lambda functions:

1. [Import an existing lambda function]({filename}50001010-cdk-fn-import-lambda.md)
2. [Using lambda layers]({filename}50001020-cdk-fn-lambda_layers.md)



134 changes: 134 additions & 0 deletions content/aws/50001010-cdk-fn-import-lambda.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
Title: How to import an existing lambda function using AWS CDK in Python
Date: 2023-11-05
Category: AWS Academy
Series: AWS CDK
series_index: 1010
Tags: aws, cdk, python
Author: Rehan Haider
Summary: A guide to importing an existing lambda function using AWS CDK in Python and applying changes to it
Keywords: lambda, cdk


We learnt [how to create a new lambda function using AWS CDK in Python]({filename}50001000-cdk-fn-create-lambda.md) in the previous post.

But in a lot of cases, you might already have a lambda function that was created elsewhere and you want to import into your CDK app and apply changes to it. In this post, we will see how to do that.

There are three ways to import an existing lambda function, can use:

1. `from_function_arn`: This relies on the ARN of the lambda function.
2. `from_function_name`: You can also import the lambda function using its name.
3. `from_function_attributes`: This is typically used to import a lambda function that was created in a different AWS account or a different region.


## Import an existing lambda function using its ARN

To import an existing lambda function using its ARN, you can use the `from_function_arn` method of the `Function` construct. Let's see how to do that.

```python
# filename: cdk_app/lambda_stack.py

from aws_cdk import (
Stack,
aws_lambda as _lambda,
)

from constructs import Construct


class LambdaStack(Stack):

FN_ARN = "arn:aws:lambda:us-east-1:123456789012:function:my-lambda"

def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)

my_lambda = _lambda.Function.from_function_arn(
self,
id="MyLambda",
function_arn=self.FN_ARN,
)
```

The `from_function_arn` method takes only three parameters:

1. `scope`: The scope of the construct. In this case, it is the `LambdaStack` class.
2. `id`: The ID that will be used within CDK/CloudFormation. In this case, we set it to `MyLambda` but it could be anything.
3. `function_arn`: The ARN of the lambda function that you want to import.

## Import an existing lambda function using its name


To import an existing lambda function using its name, you can use the `from_function_name` method of the `Function` construct. Let's see how to do that.

```python
# filename: cdk_app/lambda_stack.py

from aws_cdk import (
Stack,
aws_lambda as _lambda,
)

from constructs import Construct


class LambdaStack(Stack):

FN_NAME = "my-lambda"

def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)

my_lambda = _lambda.Function.from_function_name(
self,
id="MyLambda",
function_name=self.FN_NAME,
)
```

The `from_function_name` method takes only three parameters:

1. `scope`: The scope of the construct. In this case, it is the `LambdaStack` class.
2. `id`: The ID that will be used within CDK/CloudFormation. In this case, we set it to `MyLambda` but it could be anything.
3. `function_name`: The name of the lambda function that you want to import.


## Import an existing lambda function using its attributes

This is typically used to import a lambda function when you have the Lambda function's ARN and you also need to specify or override other attributes. E.g. for instance, if you need to specify the execution role's ARN because you want to grant permissions or interact with the role in some way within your CDK app, this method would be more suitable.

To import an existing lambda function using its attributes, you can use the `from_function_attributes` method of the `Function` construct. Let's see how to do that.

```python
# filename: cdk_app/lambda_stack.py

from aws_cdk import (
Stack,
aws_lambda as _lambda,
aws_iam as iam,
)

from constructs import Construct


class LambdaStack(Stack):
FN_ARN = "arn:aws:lambda:us-east-1:123456789012:function:my-lambda"
ROLE_ARN = "arn:aws:iam::123456789012:role/my-lambda-role"

def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)

my_role = iam.Role.from_role_arn(
self,
id="MyRole",
role_arn=self.ROLE_ARN,
)

my_lambda = _lambda.Function.from_function_attributes(
self,
id="MyLambda",
function_arn=self.FN_ARN,
role=my_role,
)
```

In the above we provided the `role` parameter to the `from_function_attributes` method. This is because we wanted to override the execution role of the lambda function. To do that, we first imported the role using the `Role.from_role_arn` method.
Loading

0 comments on commit 9fe64e0

Please sign in to comment.