AWS 람다 함수 관리 툴 – APEX (6)

dry-run으로 미리보기

Apex는 어떤 오퍼레이션에서도 --dry-run 플래그를 통해 AWS 반영없이 미리 결과를 확인해 볼 수 있습니다.

Notation

Dry run은 아래 심볼을 사용하여 리소스의 미래 상태를 표현합니다.

  • + 리소스는 생성될 것입니다.
  • - 리소스는 삭제될 것입니다.
  • ~ 리소스는 업데이트 될 것입니다.

예제

예를 들어 여러분이 foo, bar 함수를 작성했고, 아직 한 번도 배포한 적이 없다면 아래와 같은 응답을 보게 될 것입니다. 아래 아웃풋은 AWS에 전송되는 최종 요청을 나타냅니다. 충돌을 방지하기 위해 함수의 이름에 prefix를 붙이고 current 릴리즈 앨리어스를 유지하기 위해 추가 앨리어스를 붙이는 내용을 볼 수 있습니다.

$ apex deploy --dry-run

  + function testing_bar
    handler: _apex_index.handle
    runtime: nodejs
    memory: 128
    timeout: 5

  + alias testing_bar
    alias: current
    version: 1

  + function testing_foo
    memory: 128
    timeout: 5
    handler: _apex_index.handle
    runtime: nodejs

  + alias testing_foo
    alias: current
    version: 1

apex deploy foo 명령어를 실행한 후 apex deploy --dry-run 명령어를 실행했다면 아래와 같이 bar 함수만 디플로이된다는 내용을 확인할 수 있습니다.

Apex는 함수의 hash 값이 배포된 함수와 동일하면 배포하지 않습니다.

$ apex deploy --dry-run

  + function testing_bar
    runtime: nodejs
    memory: 128
    timeout: 5
    handler: index.handle

  + alias testing_bar
    alias: current
    version: 1

유사한 방법으로 설정이 변경된 부분을 미리 확인하는데도 사용할 수 있습니다.

$ apex deploy --dry-run

  ~ alias testing_foo
    alias: current
    version: $LATEST

  ~ config testing_foo
    memory: 128 -> 512
    timeout: 5 -> 10

아래는 함수 delete에 대한 preview입니다.

$ apex delete --dry-run -f

  - function testing_bar

  - function testing_foo

환경 변수

Apex는 KMS를 통해 암호화된 새로운 네이티브 AWS Lambda 환경 변수를 지원합니다. 이러한 변수를 설정하는 방법은 여러가지가 있는데 살펴보도록 합시다

-set 플래그

-s, --set 플래그는 함수 런타임에 노출되는 환경 변수를 설정하는데 사용됩니다. 예를 들어 node.js 환경에서의 process.env.NAME이나 go 언어에서의 os.Getenv("NAME")같은 값들을 말합니다. 이 플래그는 여러 번 설정할 수 있습니다.

예를 들어 여러분이 Loggly 로그 수집기를 사용하고 수집기 사용을 위해 API 토큰을 설정해야 한다면 아래와 같이 설정할 수 있습니다.

$ apex deploy -s LOGGLY_TOKEN=token log-collector

-env-file 플래그

-E, --env-file 플래그를 사용하여 여러 환경 변수를 담고 있는 JSON 파일을 반영할 수 있습니다.

$ apex deploy --env-file /path/to/env.json
// Sample env.json
{
  "LOGGLY_TOKEN": "12314212213123"
}

설정 파일 (project.json 혹은 function.json)

project.json 혹은 function.json 파일에 환경 변수를 설정하는 것도 가능합니다.

하지만 설정값은 반드시 string 타입이어야 합니다.

{
  "environment": {
    "LOGGLY_TOKEN": "12314212213123"
  }
}

우선 순위

적용 우선 순위는 아래와 같습니다.

  1. -s, --set 플래그
  2. -E, --env-file 플래그
  3. project.json 혹은 function.json 파일에 설정된 환경 변수 값

파일 무시(omitting)하기

부가적으로 .apexignore 파일을 프로젝트 루트나 특정 함수 디렉토리에 배치할 수 있으며 gitignore 파일과 동일한 패턴을 사용하여 파일을 무시할 수 있습니다. 기본적으로 .apexignore, function.json 파일은 무시됩니다.

무시된다 == 람다 함수 패키징 과정에서 포함되지 않는다

( 나머지 내용은 딱히 중요하지 않아서 번역하진 않겠습니다 ^^)

AWS 람다 함수 관리 툴 – APEX (5)

부끄러운 번역이지만 AWS 주간 소식 모음에 APEX 글이 링크되었습니다 🙂

로그 확인

Apex는 함수의 출력 로그를 보기 위해 CloudWatch Logs와 연동됩니다. apex logs에 함수의 이름이 지정되지 않으면 기본적으로 모든 함수의 로그가 표시됩니다. 로그 히스토리의 시간 범위를 지정할 수도 있고 (기본값: 5분) 아래와 같이 결과를 필터링할 수도 있습니다.

예제

최근 5분간 모든 함수의 로그 확인하기

$ apex logs

uppercase, lowercase 함수의 로그 확인하기

$ apex logs uppsercase lowercase

모든 함수의 로그를 추적(follow)하기 (tail처럼 보기)

$ apex logs -f

특정 함수의 로그 추적하기

$ apex logs -f foo

최근 1시간의 로그 보기

$ apex logs --since 1h
$ apex logs -s 1h

auth로 시작하는 모든 함수의 로그 보기

$ apex logs auth*

성능 지표(Metrics) 보기

apex metrics 명령어는 주어진 시간 동안의 함수의 실행 횟수, 총 실행 시간, 스로틀링, 에러에 대한 지표를 표시합니다.

예제

최근 24시간 동안의 모든 함수에 대한 성능 지표 보기

$ apex metrics

uppercase
  invocations: 1242
  duration: 65234ms
  throttles: 0
  error: 0

lowercase
  invocations: 1420
  duration: 65234ms
  throttles: 0
  error: 5

최근 15분동안의 지표보기

$ apex metrics --since 15m

uppercase
  invocations: 16
  duration: 4212ms
  throttles: 0
  error: 0

lowercase
  invocations: 23
  duration: 5200ms
  throttles: 0
  error: 5

인프라스트럭처 관리하기

Apex는 인프라스트럭쳐 관리를 위해 Terraform과 연동합니다. Apex는 현재 람다 함수에 대한 관리 기능만을 제공하고 있기 때문에 Lambda resource 같은 추가적인 자원을 Terraform이나 Cloudformation을 이용하여 관리하고 싶을 수 있습니다.

인프라스트럭쳐 관리

apex infra 명령어는 terraform 명령어에 대한 wrapper 입니다. Apex는 다수의 변수를 제공하고 복수의 Terraform 환경을 구성하는데 도움을 줍니다.

./infrastructure 디렉토리에 prodstage같은 환경이 존재한다면 아래와 같을 것입니다.

infrastructure/
├── prod
│   └── main.tf
├── stage
│   └── main.tf

예를 들어 apex infra --env prod plan 명령어는 아래 명령어와 동일한 일을 수행하면서 Apex에 설정된 여러 정보들을 여러가지 -var 플래그를 통해 전달해줍니다.

$ cd infrastructure/prod && terraform plan

환경에 대한 이름은 --env 플래그에 설정하거나 설정하지 않는다면 project.json에 설정된 defaultEnvironment 값이 사용됩니다.

Terraform 변수

현재 Terraform에 공개된 변수는 다음과 같습니다.

  • aws_region : us-west-2와 같은 AWS의 리전 명
  • apex_environment : prodstage같은 환경 명
  • apex_function_role : 람다 롤의 ARN
  • apex_function_arns : 모든 람다 함수의 ARN 매핑 정보
  • apex_function_names : 모든 람다 함수의 이름 매핑 정보

참고 사항

  • current라는 앨리어스가 참조되었다는 것을 지정하기 위해서는 ${apex_function_myfunction}:current를 명시적으로 할당해야 합니다.
  • apex_function_name 변수는 apex deploy를 통해 최소 1번은 배포되어야 참조할 수 있습니다.

AWS 람다 함수 관리 툴 – Apex (2)

프로젝트 구조

프로젝트는 AWS 람다 함수의 모음입니다.

설정

프로젝트 루트 디렉토리에 project.json 파일이 있습니다. 아래 예제는 모든 람다 함수에 대한 기본 AWS IAM롤과 메모리의 기본 값을 정의하고 있습니다.

{
"name": "node",
"description": "Node.js example project",
"role": "arn:aws:iam::293503197324:role/lambda",
"memory": 512
}

다중 환경

--env 플래그를 통해 복수의 환경을 지원합니다. 기본적으로 project.jsonfunction.json 파일이 이용되지만 --env 플래그가 설정되면 project.ENV.jsonfunction.ENV.json이 사용됩니다.

아래는 디렉토리 구조에 대한 예시입니다.

project.stage.json
project.prod.json
functions
├── bar
│   ├── function.stage.json
│   ├── function.prod.json
│   └── index.js
└── foo
    ├── function.stage.json
    ├── function.prod.json
    └── index.js

만약 devstaging 환경이 기본값으로 사용되길 원한다면 해당 내용을 project.jsonfunction.json에 설정하면 됩니다.

project.json
project.prod.json
functions
├── bar
│   ├── function.json
│   ├── function.prod.json
│   └── index.js
└── foo
    ├── function.json
    ├── function.prod.json
    └── index.js

Symlinks

Apex는 파일이나 디렉토리의 심볼릭 링크를 지원합니다. Apex는 링크 정보를 읽어서 함수에 포함된 파일이 아니어도 자동으로 포함시킬 것입니다.

이 기능은 npm link의 사용이나 공용 설정 등을 사용할 수 있게 해줍니다.

필드

name

프로젝트의 이름입니다. 이 필드는 복수의 프로젝트 사이에서 충돌을 막기 위한 nameTemplate의 기본값으로 사용됩니다.

  • 타입: string
  • 필수 항목

description

프로젝트에 대한 설명입니다.

  • 타입: string

runtime

function.json에 구동 환경이 별도로 설정되지 않았을 때에 함수의 기본 구동 환경을 정의합니다.

  • 타입: string

다음과 같은 구동 환경이 지원됩니다

  • java (java 8)
  • python2.7 (Python 2.7)
  • python3.6 (Python 3.6)
  • nodejs4.3 (Node.js 3.4)
  • nodejs4.3-edge (Node.js 3.4 Edge)
  • nodejs6.10 (Node.js 6.10)
  • golang (Any version)
  • clojure (Any version)
  • rust-musl[^rust-runtime][^rust-linux-only] (Any version)
  • urst-gnu[^rust-runtime][^rust-linux-only] (Any version)

[^rust-runtime] : Rust는 2가지 타입의 libc 의존성을 갖는데 rust-musl을 사용하는 것을 권장합니다. rust-gnu를 사용하면 당신의 람다 함수가 람다 서버와 당신의 PC 사이에서 glibc 버전의 불일치로 인해 실행이 거절될 수 있습니다.
[^rust-linux-only] : Rust 버전의 람다 함수는 현재 리눅스 머신에서만 빌드할 수 있습니다. 만약 Mac OS에서 빌드하려고 하면 링커 에러가 발생할 것입니다. 한 가지 솔루션은 Mac에서 apex를 Docker 컨테이너에서 실행하는 것입니다.

memory

함수의 function.json에서 별도로 설정하지 않았을 때의 기본 메모리 사용량입니다.

  • 타입: int

timeout

함수의 function.json에서 별도로 설정하지 않았을 때의 기본 타임 아웃 시간입니다.

  • 타입: int

role

함수의 function.json에서 별도로 설정하지 않았을 때의 롤입니다.

  • 타입: string

profile

사용할 AWS 프로파일의 이름입니다. 이 이름은 ~/.aws/credentials에 정의된 이름들입니다. AWS_PROFILE이나 --profile 설정을 사용하고 싶지 않다면 이 설정을 사용하세요

  • 타입: string

defaultEnvironment

기본 인프라 환경입니다.

  • 타입: string

nameTemplate

함수명을 구하는데 사용될 템플릿입니다. 기본값은 {{.Project.Name}}_{{.Function.Name}} 입니다. 예를 들어 api라는 프로젝트에 ./functions/users라는 함수가 정의되었다면 함수명은 api_users가 됩니다.

  • 타입: string

retainedVersion

함수의 function.json에서 별도로 설정하지 않았을 때의 람다 함수의 버전을 얼마나 유지할지에 대한 기본 숫자입니다.

Apex는 기본으로 10개의 버전을 유지하고 그 이전 버전의 내용은 삭제합니다. AWS는 AWS 계정 레벨에서 람다 함수들의 이전 버전 저장 공간에 대한 하드 리밋을 설정하고 있습니다.

  • 타입: int

vpc

함수의 function.json에서 별도로 설정하지 않았을 때의 기본 VPC 설정입니다.

  • 타입: object

vpc.securityGroup

보안 그룹 ID의 목록입니다.

  • 타입: array

vpc.subnets

서브넷 ID의 목록입니다.

  • 타입: array