sam init
SAM 프로젝트를 생성한다.
사용할 런타임과 빌드 툴에 따라 HelloWorld 템플릿을 고를 수 있게 되어있다.
sam init --name HelloWorldFunction
name
--name HelloWorldFunction
SAM 프로젝트 이름이다. 이 이름 값은 SAM 프로젝트에서 다양한 부분에 명명이 필요할 때 활용되고 있다.
- 람다 함수 리소스의 이름. 즉, 람다 함수의 논리적 이름. 꼭 프로젝트 이름과 람다 함수 리소스 이름을 같게 할 필요는 없다.
- SAM logs 대상을 지정할 때
sam logs -n HelloWorldFunction --stack-name firstlambda --tail
- SAM local invoke가 실행할 함수를 지정할 때
sam local invoke HelloWorldFunction --event events/event.json
- SAM build 산출물의 폴더 이름
※ 위 3가지 예시는 '람다 함수의 논리적 이름'이 '이닛 프로젝트 이름'을 그대로 사용할 때를 상정하고 있다.
이 글에서는 sam init 명령어로 생성되는 sam 프로젝트 구조를 한 번 살펴보려 한다.
프로젝트 구조
.aws-sam
폴더
프로젝트의 빌드 툴은 mvn
을 이용하고 있어서 pom.xml
파일을 확인할 수 있다.
선택지를 달리해 gradle
을 빌드 도구로 사용해도 된다.
메이븐을 빌드 툴로 두고는 있지만 sam 프로젝트에 특화된 위치에 빌드 산출물을 저장하기 위해서 mvn clean package
명령어를 쓰지 않는다.
대신 sam build
명령을 써서 프로젝트를 빌드한다.
컴파일된 클래스와 의존 jar의 저장위치는 .aws-sam/람다함수자원이름(HelloWorldFunction)/
하위이다.
.aws-sam
├── build.toml
└── build
├── template.yaml
└── HelloWorldFunction
├── lib
│ ├── joda-time.joda-time-2.6.jar
│ ├── com.amazonaws.aws-lambda-java-events-3.11.0.jar
│ └── com.amazonaws.aws-lambda-java-core-1.2.1.jar
└── helloworld
└── App.class
본인이 작성한 클래스는 App.java
뿐이고 App.class
로 컴파일되어 저장되어 있다.
pom.xml
에서 명시된 의존 라이브러리들도 전이 의존성 처리에 의해 산출물 폴더에 고이 모셔져 있다.
events
폴더
테스트 이벤트들을 정의한 파일들을 ex) event.json
두는 장소이다.
이벤트 파일 저장 위치는 이 곳에 국한될 필요는 없다.
sam local invoke
로 도커에 올린 람다에게 테스트 이벤트를 먹일 때 아래처럼 명령어를 쓰니 참고한다.
sam local invoke HelloWorldFunction --event events/event.json
event.json
예제
"Hello My App!"
람다가 문자열 타입의 이벤트를 받는다면, 이렇게 문자열을 담은 테스트 이벤트 파일을 작성하여 람다에게 먹여볼 수 있다.
람다 핸들러
이 프로젝트는 App.java
에 람다 핸들러로 쓸 메서드를 작성하고 있다.
package helloworld;
public class App {
public String hello(String name) {
return "Lambda functions are super easy and awesome!! " + name;
}
}
template.yaml
파일로 해당 메서드를 람다 함수로 지정하고, 빌드하고, AWS에 배포한다면
이 메서드가 AWS 람다 서비스의 JVM 런타임에 올라가고 입력되는 이벤트들에게 반응해 줄 것이다.
지금 구현은 문자열 이벤트를 받아 문자열을 반환하는 간단한 코드이다.
template.yaml
서버리스 자원을 선언하는 파일이다. 용법은 aws 공식 문서를 참조한다.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
firstlambda
Sample SAM Template for firstlambda
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function# More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: HelloWorldFunction
Handler: helloworld.App::hello
Runtime: java11
Architectures:
- x86_64
MemorySize: 256
서버리스 자원으로서 HelloWorldFunction
라는 AWS::Serverless::Function
타입의 자원을 선언했다.
이 타입은 aws 람다를 의미한다.
CodeUri
람다 함수의 소스코드 위치를 말한다. 이 소스코드 위치란 것은 아래 여러 관점 중 하나 이상에 해당해야 하므로 꼼꼼히 확인하자. 이 설정이 잘못되면 AWS 람다 서비스가 JVM에 올릴 클래스를 찾을 수 없어 ClassNotFound 오류를 내뱉는다.
- 이 함수의 그래이들 혹은 메이븐 프로젝트 위치: build.gradle이나 pom.xml이 있어야 한다.
- sam build 실행 후 이 함수의 컴파일된 산출물의 .aws-sam 폴더 내에서 어디에 위치하는가: 메이븐 프로젝트와 shade 플러그인을 사용할 시 .aws-sam/HelloWorldFunction에 본인이 작성한 클래스와 의존 라이브러리가 담긴다.
- 이 함수의 빌드된 산출물을 담고 있는 zip 혹은 jar 파일: 그래이들 프로젝트를 사용할 시 sam build와 매끄럽게 연계되지 않을 수가 있다. 이 때는 본인이 작성한 함수와 의존 라이브러리를 zip이나 뚱뚱한 jar로 산출하고 CodeUri에 해당 산출물의 위치를 상대경로법으로 알려줘야 한다. 상대경로 기준은 .aws-sam/HelloWorldFunction이다.
HelloWorldFunction
이라 함은, sam 빌드 산출물 폴더 내에있는 .aws_build/HelloWorldFunction
에 산출물 코드가 있음을 뜻한다.
이 부분을 수정해서 메이븐 빌드 산출물인 target/helloWorld.jar
뚱뚱한 jar를 지정하는 일도 가능하다.
Handler
핸들러 메서드의 FQN을 정확히 명시한다. 패키지명.클래스명::메서드명
Runtime
java8, java11 따위. 람다가 올라갈 런타임을 설정한다.
기타
나머지 설정들 역시 aws 람다를 생성할 때 필요한 부수적인 값들이다.
pom.xml
Hello World 템플릿이 선언해준 의존성 형태는 아래와 같다.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>helloworld</groupId>
<artifactId>HelloWorld</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>A sample Hello World created for SAM CLI.</name>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>3.11.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<configuration>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
메이븐 셰이드 플러그인은 sam과는 관계없는 독립적인 플러그인인데, 뚱뚱한 jar 파일을 만들어 준다.
콘솔에서 직접 mvn clean package
를 타이핑하면 target
디렉터리에 뚱뚱한 jar가 산출되는 걸 볼 수 있다.
이와 반대로 sam build
로 빌드하여 .aws-build
디렉터리를 까보면? 뚱뚱한 jar가 없다는 사실.
jar의 메서드를 람다 핸들러로 지정하려면 template.yaml
에서 CodeUri
를 변경한다, target
폴더와 jar 파일을 가리키도록.
samconfig.toml
sam deploy
로 서버리스 자원을 배포하게 되면 만들어지는 파일이다.
맨 처음 배포시에는 --guided
옵션을 이용해 대화형으로 배포 설정들을 입력하게 된다.
입력 후에 결정된 값들이 (s3 버킷 주소, cloudformation 스택 따위) samconfig.toml
에 보관되어
추후 배포시 재사용할 수 있게 된다.
따라서 다음번에는 sam deploy
두 단어만으로 서버리스 자원을 재배포할 수 있다.
파일의 내용은 대충 이러하다.
version = 0.1
[serverless]
[serverless.deploy]
[serverless.deploy.parameters]
stack_name = "firstlambda"
s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-e3df9gfc8va7"
s3_prefix = "firstlambda"
region = "ap-northeast-1"
profile = "serverless"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"
disable_rollback = true
image_repositories = []
'컴퓨터공학 > 서버리스' 카테고리의 다른 글
[AWS][API Gateway] API Gateway 유형에 따른 ALB Private Integration 차이 /w VPC Link (2) | 2022.09.08 |
---|---|
[AWS][SAM] 오류 핸들링 (0) | 2022.04.04 |
[AWS][SAM][강의노트] 자바 런타임에서 람다 클래스의 수명 (0) | 2022.03.24 |
[AWS][SAM][강의노트] 다양한 시그니처의 람다 작성해보기 (0) | 2022.03.11 |