AWS Lambda 를 활용해서 간단한 Batch 작업 처리하기

어느 정도 규모의 시스템을 구축하다 보면 다양한 배치작업이 필요한 일이 생기게 된다.

가령 특정 기간동안 유저의 거래 통계를 빠르게 조회하기 위해서 data warehouse 에 저장하거나 혹은 유저에게 주기적으로 특정 이메일을 보내는 등 특정 기간에 걸쳐 어떠한 행위를 반복적으로 처리해야 할 일이 생긴다. 이러한 배치작업을 처리하기 위해서 과거에는 unix cron job 등을 통해 이러한 배치작업을 처리했다.

하지만 이러한 cron 작업의 경우 단일 server 에서 하나의 프로세스로 돌아가는 만큼 그 안정성과 소스의 관리라는 측면에서 불안한 것이 사실이었고, 사실 해당 server 의 네트워크 상태가 불안정하거나 혹은 프로세스 또는 운영체제가 종료되는 경우 배치작업에 지장이 생기게 된다.

AWS 에서는 cloudwatch 와 lambda 를 통해 이러한 다양한 배치작업을 처리할 수 있는 기능을 제공하고, 이번 포스트에서는 이처럼 AWS 라는 클라우드 환경에서의 배치작업 처리를 다루어 보고자 한다.

What is AWS cloudwatch?

AWS cloudwatch 란 AWS 의 cloud resource 및 어플리케이션에 대한 monitoring service 이다.

간단하게 설명하면, AWS 에서 여러 자원을 사용하고 또 어플리케이션을 동작하면 AWS 는 이를 모두 클라우드 환경에서 실행하기 때문에 실제 bare metal 을 사용할때처럼 내가 사용하고자 하는 컴퓨팅 자원의 상태 및 로그등을 정확히 알기가 힘들다. 이를 해결하기 위해 AWS 는 각종 cloud resource 를 사용자가 쉽게 관리할 수 있도록 시각화시켜 내 클라우드 자원들이 잘 동작하고 있는지 알 수 있도록 별도의 서비스를 제공하고 이것이 바로 Cloudwatch 이다.

Cloudwatch 서비스를 이용하여 AWS 상에서 구동되고 있는 다양한 컴퓨팅 자원들의 상태를 리포팅 받고 또 시스템 로그들을 매우 간편하게 확인할 수 있다. 뿐만 아니라 여러 컴퓨팅 자원들을 지켜보며 특정 상황이나 시점에서 어떤 event 를 발생시킬 수도 있다.

종합하면, AWS 자원들을 모니터링 하는 cloudwatch 에서 내 자원들을 모니터링 할 수 있고, event 라는 개념을 통해 특정 시간 혹은 조건에 따라 어떤 event 를 만들고 이 event 가 어떤 행위를 일으킬 수 있다. 이러한 행위의 종류는 다양한데 이번 포스트에서는 특정 람다를 실행시키는 행위를 발생시켜 이를 통해 일련의 배치작업을 처리해 보고자 한다.

간략한 동작 순서

이번 포스트에서 배치작업은 다음의 순서에 따라 이루어 진다.

  1. AWS Cloudwatch 에 특정 시간마다 특정 람다를 호출하도록 하는 event 를 등록한다.
  2. Cloudwatch 는 위에서 설정한 내용에 따라 주기적으로 event 를 발생시키고 즉, 람다를 호출한다.
  3. 사용자가 특정 시간마다 호출된 람다 함수를 작성한다.
  4. 특정 시간 조건이 충족되면 람다함수가 호출된다.

이처럼 아주 간단한 절차에 따라 배치함수가 동작되고, 배치함수의 성공 유무 등 잘 동작하고 있는지 cloudwatch 에서 확인이 가능하다.

Getting started

자 이제 실제로 구현을 해보도록 하자!!

이와 같은 일련의 과정을 AWS console 을 통해 하는 것은 너무도 성가시고 실수에 취약하므로 본 포스트에서는 terraform 이라는 Infrastructure as Code 툴을 사용하며 terraform 을 모른더라도 pseudo code 라는 생각으로 보아도 쉽게 이해할 수 있으니 실제 terraform 이 궁금한 독자분이 계시다면 구글링을 통해 살펴보기 바란다…ㅎㅎ

제일 먼저 아래와 같이 매 시간마다 호출될 람다 함수를 만들어 보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
resource "aws_lambda_function" "TestFunction" {
filename = "${path.module}/zips/TestFunction.zip"
source_code_hash = "${filebase64sha256("${path.module}/zips/TestFunction.zip")}"
function_name = "TestFunction"
role = "${aws_iam_role.iam_role_for_lambda.arn}"
handler = "index.lambda_handler"
runtime = "python3.6"
memory_size = "512"

vpc_config {
subnet_ids = ["${var.private_subnet_az1_id}"]
security_group_ids = ["${aws_security_group.lambda_sg.id}"]
}

timeout = "100"
}

코드를 할번 살펴보면 람다함수를 작성하고 이를 zip 파일로 압축하여 terraform 을 통해 zip 파일을 업로드하고 람다함수를 배포하는 것을 알 수 있다. Source_code_hash 는 현재 zip 파일의 hash를 통해 업데이트 되었다면 업데이트된 파일을 aws 로 업로드 하기 위함이며, role 에서 이 람다함수가 어떤 AWS 리소스들에 접근할 수 있을지에 대한 role을 넣어준다.

vpc_config 의 경우 어떤 vpc와 security group 에 속하는지 등을 표기한다.

다음으로는 아래와 같이 cloudwatch 에서 특정 시간마다 일으킬 이벤트 규칙을 정의한다.

1
2
3
4
5
6

resource "aws_cloudwatch_event_rule" "every_10pm" {
name = "every-10-pm"
description = "Fires every 10 pm"
schedule_expression = "cron(0 13 * * ? *)"
}

이벤트 규칙은 cron expression 으로 표현되니 자세한 문법은 cron expression 을 참조하길 바란다.

다음으로는 아래처럼 위 이벤트 규칙의 대상을 설정해 준다.

1
2
3
4
5
6

resource "aws_cloudwatch_event_target" "search_naver_every_10pm" {
rule = "${aws_cloudwatch_event_rule.every_10pm.name}"
target_id = "TestFunction"
arn = "${aws_lambda_function.TestFunction.arn}"
}

코드를 살펴보면 특정 이벤트 규칙이 어떤 람다 함수를 호출할지 해당 람다 함수의 ARN 을 통해 가르쳐 주고 있다.

마지막으로는 Cloudwatch 에게 람다함수를 호출 할 수 있는 권한을 주는 것이다.

1
2
3
4
5
6
7
resource "aws_lambda_permission" "allow_cloudwatch_to_call_search_naver" {
statement_id = "AllowExecutionFromCloudWatch"
action = "lambda:InvokeFunction"
function_name = "${aws_lambda_function.TestFunction.function_name}"
principal = "events.amazonaws.com"
source_arn = "${aws_cloudwatch_event_rule.every_10pm.arn}"
}

이것이 무슨말인지 잘 이해가 되지 않을 수 있다. cloudwatch 가 lambda 를 호출할 권한이라니? Cloudwatch 가 무슨 사람이라도 된단 말인가!?

AWS 에서는 여러 AWS 서비스가 다른 서비스의 어떤 작업을 수행하기 위한 자격을 부여할 수 있고 이러한 자격을 IAM Role 이라고 한다.

코드를 한번 살펴보면 위에서 principal 이란 어떤 AWS 서비스에게 권한을 부여할 것인지를 나타내고 여기서는 events.amazonaws.com (이는 아마존에서 정해둔 AWS 서비스에 대한 도메인이다.) 즉, cloudwatch 에서 발생하는 특정 event 에게 어떤 권한을 부여하겠다는 것이다. 또 action 에서는 “lambda:InvokeFunction” 즉 cloudwatch 이벤트로 하여금 어떤 람다함수를 호출할수 있는 권한을 부여한다 정도로 이해하면 되겠다. arn 은 물론 어떤 람다함수인지를 알려주는 것으로, 해당 람다 함수의 고유 id라고 이해하면 된다.

마지막으로 해야할 것은 위의 람다함수가 실행되면서 발생한 로그를 저장할 log group 을 설정해 주는 것이데 이는 아래와 같이 설정한다.

1
2
3
4
5

resource "aws_cloudwatch_log_group" "example" {
name = "/aws/lambda/TestFunction"
retention_in_days = 14
}

여기서 name 은 내 멋대로 하면 되나 싶지만 그렇지 않다.

위처럼 /aws/lambda/함수명 이라는 이름으로 정확히 log group 을 만들어주어야 아마존 람다가 해당 log group 에 로그를 쌓게 되니 주의하기 바란다.

Google API 사용을 위한 OAuth 2.0 적용

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×