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 (1)

apex

APEX는 AWS의 람다 함수의 빌드와 배포를 도와주는 툴입니다. AWS CLI로도 가능하지만 훨씬 간편하게 이용할 수 있습니다.

Github Repository
Homepage

설치

맥, 리눅스, OpenBSD에서는

curl https://raw.githubusercontent.com/apex/apex/master/install.sh | sh

윈도우에서는 바이너리 설치 파일을 받아서 설치할 수 있습니다.

AWS Credential

여타의 AWS 관련 툴과 마찬가지로 Credentail은 ~/.aws 폴더에 설정된 내용을 참고합니다.

설정되어 있지 않다면 aws configure 명령어로 설정할 수 있습니다.

Profile flag

--profile 역시 사용할 수 있습니다.

$ apex --profile my-profile deploy

Project configuration

프로젝트 실행 환경에 대한 설정을 project.json 파일을 통해서 할 수 있는데 이 파일에 Credential에 대한 profile을 지정할 수 있습니다.

아래는 제가 사용하는 설정입니다. Lambda 함수를 만들 때 사용되는 설정값들을 확인할 수 있습니다.

{
  "name": "aws-utils",
  "description": "AWS Utils",
  "memory": 128,
  "timeout": 5,
  "role": "arn:aws:iam::....",
  "environment": {},
  "runtime": "python3.6"
}

IAM Role

IAM Role에 대한 설정도 profile과 같이 --iamrole 옵션 혹은 project.json 파일을 통해서 설정할 있습니다.

Credential 참조 순서

AWS Credential 정보를 로딩하는 우선 순위는 다음과 같습니다.

  1. 플래그로 설정된 프로파일
  2. JSON 설정 파일(project.json)에 설정된 profile
  3. 환경 변수에 설정된 프로파일
  4. default 라는 이름의 프로파일

IAM 정책

Apex는 람다 함수의 배포 및 관리를 위해서 다음과 같은 IAM 권한이 필요합니다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "iam:CreateRole",
        "iam:CreatePolicy",
        "iam:AttachRolePolicy",
        "iam:PassRole",
        "lambda:GetFunction",
        "lambda:ListFunctions",
        "lambda:CreateFunction",
        "lambda:DeleteFunction",
        "lambda:InvokeFunction",
        "lambda:GetFunctionConfiguration",
        "lambda:UpdateFunctionConfiguration",
        "lambda:UpdateFunctionCode",
        "lambda:CreateAlias",
        "lambda:UpdateAlias",
        "lambda:GetAlias",
        "lambda:ListAliases",
        "lambda:ListVersionsByFunction",
        "logs:FilterLogEvents",
        "cloudwatch:GetMetricStatistics"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}

또한 apex init 과정에서 AWSLambdaVPCAccessExecutionRole이라는 정책이 자동으로 생성됩니다.

Getting started

Apex를 사용하기 위해서는 초기화 과정이 필요합니다.

$ export AWS_PROFILE=xxx
$ apex init

아래와 같은 화면을 볼 수 있으며 초기화 과정 중에 위에서 언급한 Apex가 사용할 IAM 역할 및 정책이 생성되고 project.json 파일과 functions라는 폴더도 생성됩니다.

functions 폴더에는 테스트용 람다 함수(functions/hello/index.js)도 만들어집니다.

console.log('starting function')
exports.handle = function(e, ctx, cb) {
  console.log('processing event: %j', e)
  cb(null, { hello: 'world' })
}

이 테스트용 함수를 바로 디플로이해볼 수 있습니다.

# project.json 파일이 있는 폴더에서 실행
$ apex deploy
$ apex invoke hello
{"hello": "world"}