---
# System prepended metadata

title: Asset for Lambda developer
tags: [SAM, Lambda, CDK, Python]

---

# Asset for Lambda developer

## Lambda 생성
콘솔에서 Lambda를 생성합니다. 


새로작성을 클릭합니다.
함수이름을 작성 : 'MyLambda'
런타임을 선택 : 'Python 3.7'
아키텍처 : x86_64

코드 편집기에 아래 코드를 입력합니다. 

```python=
import json
import pandas as pd
import boto3 

def lambda_handler(event, context):
    dynamo = boto3.client('dynamodb')


    # creating and initializing a list
    values= [['Rohan',455],['Elvish',250],['Deepak',495],
             ['Soni',400],['Radhika',350],['Vansh',450]]
     
    # creating a pandas dataframe
    df = pd.DataFrame(values,columns=['Name','Total_Marks'])
     
    # Applying lambda function to find
    # percentage of 'Total_Marks' column
    # using df.assign()
    df = df.assign(Percentage = lambda x: (x['Total_Marks'] /500 * 100))
     
    # displaying the data frame
    print(df)
```

## Lambda 계층을 사용하여 AWS Lambda에 외부 Python 라이브러리 추가

아래와 같이 Lambda를 사용할때 Pandas 또는 Numpy를 사용하는 방법을 알려드리겠습니다.

```python=
import pandas as pd
import numpy as np
```

가자 좋은 방법은 Layer를 사용하는 것입니다. 공통의 Layer를 만들어서 라이브러리, 종속성을 패키징하여 여러 Lambda가 공유해서 사용할 수 있습니다. 

방법은 아래와 같습니다. 

1. AWS에서 람다 함수 생성 및 테스트
1. 로컬 컴퓨터에 패키지를 설치하고 압축
1. 람다 레이어 생성 및 패키지 업로드
1. 레이어를 람다에 연결하고 테스트

Lambda와 Layer를 연결할때 빌드 의존성이 있는경우, version과 환경을 맞춰야합니다. 기본적으로 Lambda는 리눅스 위에서 동작합니다. 

### Cloud9에 패키지 설치

Cloud9 Terminal에 아래 명령을 작성합니다. 

```bash=
mkdir packages
cd packages
```

다음으로 venv라는 가상 환경을 만들고 아래 명령을 차례로 실행하여 가상 환경을 활성화합니다.

```bash=
python3 -m venv venv
source venv/bin/activate
```


이제 가상 환경이 활성화되어야 합니다. 그리고 "python"이라는 폴더를 만들고 아래 명령을 차례로 실행하여 python 디렉토리로 이동합니다.

```bash=
mkdir python
cd python
```

python이라는 디렉토리를 만드는 것이 중요합니다. (이것은 람다 레이어로 작업할 때 필수입니다.)이제 python 디렉토리에 있으므로 아래 명령을 차례로 실행하여 pandas를 설치한 다음 numpy를 설치하십시오. 
:::info
package와 lambda의 파이선 버전이 사용가능해야합니다.
:::
```bash=
pip install pandas -t .
pip install numpy -t .
````

pip를 사용하여 현재 디렉터리(python)를 대상으로 지정하는 패키지를 설치하고 있습니다. 설치가 완료될 때까지 기다리십시오.

이것이 우리가 람다에 사용할 패키지입니다. 압축하기 전에 용량을 줄이기 위해 폴더에서 확장자가 ".dis-info"인 객체를 삭제합시다.

```bash=
rm -rf *dist-info
```

관련 패키지만 남기고 상위 폴더로 이동합니다. 

```bash=
cd ..
```
이제 python 디렉터리를 압축하고 "panda-numpy-package.zip"이라는 이름을 지정합니다. 
```bash=
zip -r panda-numpy-package.zip python
```

해당파일을 다운로드합니다. 또는 s3에 업로드합니다. 
AWS lambda로 이동합니다. 
왼쪽 네비게이션 바에서 추가리소스>계층을 선택합니다. 
계층 생성 버튼을 클릭합니다.
layer의 이름을 지정하고 .zip업로드를 선택합니다. 
업로드 버튼을 클릭하고 다운로드 받은 파일을 클릭합니다. 
만약 amazon s3로 업로드했다면 리소스의 https 경로를 지정합니다. 
생성을 클릭합니다. 
이전에 생성한 Lambda를 클릭하고 스크롤을 내려 계층의 Add a Layer를 클릭합니다. 
사용자 지정 계층에서 업로드한 Layer를 선택하고 버전을 지정합니다. 
추가버튼을 클릭합니다.


## python-lambda-layer-creation을 사용한 Python Lambda Layer 생성
환경 및 버전을 맞춰서 layer를 생성하는건 귀찮습니다. 
AWS Serverless Application Repository콘솔에서 Python Lambda Layer를 생성하는 커스텀 어플리케이션을 사용해보겠습니다. 

AWS Lambda콘솔의 왼쪽 네비게이션 바의 애플리케이션을 클릭합니다.
애플리케이션 생성을 선택하고 서버리스 애플리케이션 탭을 클릭합니다. 
python-lambda-layer-creation을 검색합니다. 그리고 사용자 지정 IAM역할 또는 리소스 정책을 생성하는 앱 표시를 체크합니다. 
![](https://hackmd.io/_uploads/rkSMbps33.png)
python-lambda-layer-creation을 선택합니다. 

이 앱이 사용자 지정 IAM 역할을 생성한다는 사실을 확인합니다(I acknowledge that this app creates custom IAM roles)를 선택한 다음 배포(Deploy)를 선택합니다.

serverlessrepo-python-lambda-layer라는 이름의 람다가 하나 생성됩니다. 이 람다는 Payload로 던저진 값에 맞춰서 layer를 생성합니다. 해당 Lambda의 버전을 원하는 python 버전으로 변경합니다. 

해당 람다함수로 이동하여 test를 클릭하고 이벤트 json에 아래 값을 입력합니다. 
```jsonld=
{
  "dependencies": {
    "requests": "latest",
    "numpy": ">=0.0.0",
    "pandas": ">=0.0.0",
    "urllib3":"==1.26.7"
  },
  "layer": {
    "name": "a-sample-python-lambda-layer",
    "description": "this layer contains requests, numpy and keyring libraries",
    "compatible-runtimes": [
      "python3.9"
    ],
    "license-info": "MIT"
  }
}
```
(python 3.9의 경우 Urllib3 종속성 에러로 1.26.7로 고정, 다른버전 사용시 삭제해도 상관 없음)

함수 동작이 완료되고 200이 떨어지면, lambda의 Layer를 생성된 레이어로 바꾸고 python의 버전을 3.11로 변경하여 다시 실행해봅니다.

# with CDK
기존 생성된 CDK프로젝트의 스택에 Lambda와 레이어를 추가하겠습니다. 레이어를 프로젝트에 포함시킬 수도 있고, 레이어의 Arn만 추가하는 방법도 있습니다. 

먼저 resource/lambda폴더를 생성하고 lambda.py파일을 만듭니다. lambda.py는 기존의 lambda코드를 붙여넣습니다. 

기존생성된 cdk프로젝트의 스택 적절한 부분에 아래 코드를 추가합니다.
- 레이어 arn 추가하기
```typescript=
 const lambdafunction = new lambda.Function(this, 'pythonLambda', {
      runtime: lambda.Runtime.PYTHON_3_7,
      code: lambda.Code.fromAsset('resources/lambda'),
      handler: 'lambda.lambda_handler',
 
    }
    );
    lambdafunction.addLayers(
      lambda.LayerVersion.fromLayerVersionArn(this, 'awsNumpyLayer', 'arn:aws:lambda:us-east-1:566034038752:layer:panda-numpy:8')
    )
```
- 레이어를 Cdk 프로젝트에 추가하기
```typescript=
const layer = new lambda.LayerVersion(this, 'pythonlasyer', {
      code: lambda.Code.fromAsset('resources/layers/packages/python'),
      description: 'Common helper utility',
      compatibleRuntimes: [lambda.Runtime.PYTHON_3_7],
      removalPolicy: cdk.RemovalPolicy.DESTROY
});
const lambdafunction = new lambda.Function(this, 'pythonLambda', {
      runtime: lambda.Runtime.PYTHON_3_7,
      code: lambda.Code.fromAsset('resources/lambda'),
      handler: 'lambda.lambda_handler',
      layers: [layer]

});
```
그리고 생성된 패키지 파일을 'resources/layers/packages/python'안에 위치합니다. 

### CDK Lambda Local debug

CDK를 빌드해 정상적으로 Cfn template가 출력되는지 확인합니다. 
```bash=
CDK synth
```

## (추가)Cloud9 upgrade python3.11

### Step One: install python3.11

```
sudo yum update -y
sudo yum erase openssl-devel -y
sudo yum install openssl11 openssl11-devel  libffi-devel bzip2-devel wget -y
wget https://www.python.org/ftp/python/3.11.4/Python-3.11.4.tgz
tar -xf Python-3.11.4.tgz
cd Python-3.11.4/
./configure --prefix=/usr --enable-optimizations
make -j $(nproc)
sudo make altinstall
python3.11 -V
```

NOTE: make -j $(nproc) This command will take a long time to complete. Please be patient.

### Step Two: install pip

```
sudo yum install python3-pip
```
### Step Three: install pylint
```
sudo yum makecache
sudo yum -y install pylint
```
### Step Four: Switch python3 from python3.x to python3.11

```
sudo ln -sf /usr/bin/python3.11 /usr/bin/python3
```
NOTE: The path might be different.

Congratulations! Python3.11 is installed.

Let's test it

In the IDE create a file test.py with two lines of code
```
import sys
print (sys.version)
```
On the menu bar, click Run > Run With > Python 3, then python version will show, such as:
```
3.11.4
```
### Step Five: Give the IDE a new Pylint

Now we need to get the Pylint working too, for proper error checking.

Open the pylint file.

```
vi ~/.c9/python3/bin/pylint
``` 
Change the very first line to following
```
#!/usr/bin/python3.11
```
NOTE: The path of python3.11 might be different

And save

Sometimes it won’t take effect immediately, just close all the tabs(files) on the IDE and reopen again.

Congratulations, Again! All done

let's try python’s new match pattern feature

``` 
def color(color):
    match color:
        case "red":
            print("I am red")
        case "blue":
            print("I am blue")
        case _:
            print("I am blank")
             
color("red")
color("blue")
color("love")
```
 


# With AWS SAM

https://catalog.us-east-1.prod.workshops.aws/workshops/d21ec850-bab5-4276-af98-a91664f8b161
 
### AWS SAM Local (Debug)

AWS SAM Local호출은 Lambda 호출을 한번 완료된 후 함수를 종료합니다.

기본적으로 이 명령을 사용하는 경우AWS SAMCLI는 현재 작업 디렉토리가 프로젝트의 루트 디렉토리라고 가정합니다. 이 AWS SAMCLI는 먼저 sam build 명령을 사용하여 template.yaml또는template.yml을 찾습니다. 그런 다음 AWS SAM CLI가 현재 작업 디렉터리에서 template.yaml 또는 template.yml 라는 템플릿 파일을 찾습니다.

1. AWS SAM workshop을 진행할때, SAM의 로컬 디버깅을 테스트해봅니다. 위치는 SAM프로젝트의 루트여야합니다.
    ```bash=
    sam local invoke 
    ```
    ![](https://i.imgur.com/vXObdO4.png)

1. AWS SAM Local Start-Lambda로 테스트해보겠습니다. 이 방식을 사용하면 Lambda함수를 로컬에서 프로그래밍 방식으로 호출할 수 있습니다.
    ```bash=
    sam local start-lambda 
    ```
1. 이제 엔드포인트를 통해 템플릿에 정의된 Lambda 함수를 호출할 수 있습니다.
    ```bash=
    aws lambda invoke --function-name "HelloWorldFunction" --endpoint-url "http://127.0.0.1:3001" --no-verify-ssl out.txt
    ```
1. 로컬의 함수결과를 out.txt에서 확인할 수 있습니다. 
1. 이 방법을 사용하면 로컬 Lambda의 엔드포인트에 대해 테스트를 실행 할 수 있습니다. 


### AWS DynamoDB Local (보류)
https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/DynamoDBLocal.DownloadingAndRunning.html#docker

Amazon DynamoDB의 다운로드 가능 버전을 사용하면 DynamoDB 웹 서비스에 액세스하지 않고도 애플리케이션을 개발하고 테스트할 수 있습니다. 대신, 데이터베이스가 컴퓨터에서 독립형으로 실행됩니다. 프로덕션 환경에서 애플리케이션을 배포할 준비가 되면 코드에서 로컬 엔드포인트를 제거한 다음 DynamoDB 웹 서비스를 가리킵니다.

이 로컬 버전을 통해 처리량, 데이터 스토리지 및 데이터 전송 요금을 절감할 수 있습니다. 또한, 애플리케이션 개발 중에 인터넷 연결이 필요 없습니다.
Amazon DynamoDB의 다운로드 가능 버전은 도커 이미지로 제공됩니다. 자세한 내용은 dynamodb-local 단원을 참조하세요.

DynamoDB Local을 AWS Serverless Application Model(AWS SAM)에 빌드된 REST 애플리케이션의 일부로 사용하는 예제는 주문 관리를 위한 SAM DynamoDB 애플리케이션을 참조하세요. 이 샘플 애플리케이션은 테스트를 위해 DynamoDB Local을 사용하는 방법을 보여 줍니다.

DynamoDB Local 컨테이너도 사용하는 다중 컨테이너 애플리케이션을 실행하려면 Docker Compose를 사용하여 DynamoDB Local을 비롯한 애플리케이션의 모든 서비스를 정의하고 실행합니다.

1. Docker compose를 사용하여 DynamoDB local을 설치하고 실행하는 방법
1. Docker desktop을 다운로드하여 설치합니다.
    ```bash=
    sudo curl  -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
    sudo chmod +x /usr/local/bin/docker-compose
    ```

1. 다음 코드를 파일에 복사하고 docker-compose.yml로 저장합니다.
    ```yaml=
    version: '3.8'
    services:
      dynamodb-local:
        command: "-jar DynamoDBLocal.jar -sharedDb -dbPath ./data"
        image: "amazon/dynamodb-local:latest"
        container_name: dynamodb-local
        ports:
          - "8000:8000"
        volumes:
          - "./docker/dynamodb:/home/dynamodblocal/data"
        working_dir: /home/dynamodblocal
    ```    
1. 이 docker-compose.yml 스크립트는 app-node 컨테이너와 dynamodb-local 컨테이너를 만듭니다. 이 스크립트는 app-node 컨테이너에서 AWS CLI를 사용하여 dynamodb-local 컨테이너에 연결하고 계정 및 테이블 제한을 설명하는 명령을 실행합니다.
 
1. YAML 스크립트를 사용하려면 AWS 액세스 키와 AWS 보안 키를 지정해야 하지만 유효한 AWS 키가 없어도 DynamoDB Local에 액세스할 수 있습니다.

1. 다음을 실행합니다.

```bash=
docker-compose up
 ```
# AWS Lambda Power tools 
https://awslabs.github.io/aws-lambda-powertools-typescript/latest/
# AWS Lambda Code Tuning
https://awslabs.github.io/aws-lambda-powertools-python/latest/tutorial/#project-structure
# AWS Lambda Power Tuning tools
https://github.com/alexcasalboni/aws-lambda-power-tuning

AWS Lambda Power Tuning은 데이터 기반 방식으로 비용 및/또는 성능에 대해 Lambda 함수를 최적화하는 데 도움이 되는 AWS Step Functions로 구동되는 상태 머신입니다.

상태 머신은 배포하기 쉽고 빠르게 실행할 수 있도록 설계되었습니다. 또한 언어에 구애받지 않으므로 계정의 모든 Lambda 함수를 최적화할 수 있습니다.

기본적으로 Lambda 함수 ARN을 입력으로 제공할 수 있으며 상태 시스템은 여러 전원 구성(128MB에서 10GB, 값 결정)으로 해당 함수를 호출합니다. 그런 다음 모든 실행 로그를 분석하고 비용을 최소화하고 성능을 최대화하기 위한 최상의 전원 구성을 제안합니다.

입력 기능은 실제 HTTP 요청, SDK 호출, 콜드 스타트 등을 수행하는 AWS 계정에서 실행됩니다. 상태 시스템은 교차 리전 호출도 지원하며 병렬 실행을 활성화하여 단 몇 초 만에 결과를 생성할 수 있습니다.

### 상태 머신은 어떻게 생겼습니까?
매우 간단하며 AWS 관리 콘솔에서 각 단계를 시각적으로 확인할 수 있습니다.

![](https://i.imgur.com/HBds5n4.png)

### Lambda Power Tuning에서 어떤 결과를 기대할 수 있습니까?
상태 머신은 각 전원 구성에 대한 평균 비용 및 속도의 시각화를 생성합니다.

예를 들어, 다음은 더 많은 전력으로 더 저렴하고 빨라지는 두 개의 CPU 집약적 기능에 대한 결과입니다.

![](https://i.imgur.com/affL23E.png)
차트 해석하는 방법: 실행 시간은 128MB의 경우 35초에서 1.5GB의 경우 3초 미만으로, 실행 비용은 14% 저렴합니다.

![](https://i.imgur.com/5O1nb5a.png)

차트 해석하는 방법: 동일한 평균 비용으로 실행 시간이 128MB의 경우 2.4초에서 1GB의 경우 300ms로 증가합니다.

### 배포방법

1. 로컬 환경에 AWS SAM CLI를 설치합니다.
1. AWS 자격 증명 구성(AWS CLI 설치 필요):
    ```bash=
    $ aws configure
    ```
1. 레포지토리 클론
    ```bash=
    $ git clone https://github.com/alexcasalboni/aws-lambda-power-tuning.git
    ```
1. Lambda 계층 및 기타 종속성을 구축합니다.
    ```bash=
    cd ./aws-lambda-power-tuning
    sam build -u
    ```
1. sam build -u는 함수가 실행되는 환경과 유사한 환경을 제공하는 Docker 컨테이너 이미지를 사용하여 SAM 빌드를 실행합니다. SAM 빌드는 차례로 AWS SAM 템플릿 파일에서 이 프로젝트의 Lambda 함수 및 계층에 대한 정보를 확인합니다.
1. 빌드가 완료되면 Build Succeeded라는 출력이 표시되어야 합니다. 그렇지 않은 경우 무엇이 잘못되었는지에 대한 지침을 제공하는 오류 메시지가 표시됩니다.
1. SAM 배포 "guided" 모드를 사용하여 애플리케이션을 배포합니다.
    ```bash=
    sam deploy -g
    ```
1. sam deploy -g는 도구 배포 프로세스를 안내하는 간단한 프롬프트를 제공합니다. 'Stack Name'에 고유한 이름(ex :aws-lambda-power-tuning)을 제공하고 도구를 실행할 AWS 리전을 제공하면 이 도구의 테스트를 위한 기본값을 선택할 수 있습니다. "Y"로 표시된 질문을 수락한 후 선택적으로 애플리케이션 구성을 저장할 수 있습니다.
    ![](https://i.imgur.com/3RSNGKf.png)
1. 그런 다음 SAM CLI는 Lambda Power Tuning 도구에 대한 리소스를 생성하는 데 필요한 명령을 실행합니다. 표시된 CloudFormation 출력은 문제 또는 실패를 강조 표시합니다.
1. 문제가 없으면 완료되면 스택 출력과 성공적으로 생성/업데이트된 스택 메시지가 표시됩니다.

## 실행방법
1. Stepfunction 콘솔로 이동합니다. 
    https://us-west-2.console.aws.amazon.com/states/home?region=us-west-2

    ![](https://i.imgur.com/BUiXP9j.png)

1. 생성된 상태머신을 클릭합니다. powerTuningStateMachine-xxxx형태의 이름으로 되어있습니다.
1. 다음 Start excution을 선택합니다. 
1. input에 아래와 같은 값을 넣습니다. 
    ```json=
    {
        "lambdaARN": "your-lambda-function-arn",
        "powerValues": [128, 256, 512, 1024, 1536, 2048, 3008],
        "num": 50,
        "payload": {},
        "parallelInvocation": true,
        "strategy": "cost"
    }
    ```
1. "your-lambda-function-arn"에 AWS SAM실습에 사용한 Lambda의 ARN을 입력합니다. 
1. Start excution을 클릭합니다. 
    ![](https://i.imgur.com/22TqgLG.png)
1. 상태머신 동작이 완료하면 상단의 execution output을 클릭합니다. 
1. "visualization" 항목의 주로를 브라우저에 붙여넣습니다. 
    ![](https://i.imgur.com/5zHZPrx.png)
1. 위와 비슷한 결과를 얻을 수 있습니다. 사용하는 람다의 가장 최적화된 리소스를 할당해서 사용하세요. 


# AWS CDK Workshop
https://catalog.us-east-1.prod.workshops.aws/workshops/071bbc60-6c1f-47b6-8c66-e84f5dc96b3f/ko-KR

# AWS SAM local with CDK
https://docs.aws.amazon.com/ko_kr/serverless-application-model/latest/developerguide/serverless-cdk-getting-started.html

참고영상
- AWS Lambda 기초부터 실전까지: https://www.youtube.com/watch?v=BcoekcPRKWc&list=PLORxAVAC5fUWoPJqJxJavUNK_QI8EFWP_
- AWS의 Serverless 개발 프레임워크 SAM 빠르게 감 잡기 : https://www.youtube.com/watch?v=GzUBZIVZPgY&list=PLORxAVAC5fUWoPJqJxJavUNK_QI8EFWP_&index=2 
- AWS에서 Serverless 개발 시작하기 : https://www.youtube.com/watch?v=Y6U8Y2gnHkc&list=PLORxAVAC5fUWoPJqJxJavUNK_QI8EFWP_&index=3
- AWS에서 DevOps - CI/CD 시작하기 : https://www.youtube.com/watch?v=E1wHAlJUk2w&list=PLORxAVAC5fUWoPJqJxJavUNK_QI8EFWP_&index=8