BLOG

AWS Lambda 가이드 (with Python)
작성일: 2016-09-13

AWS Lambda가 서울리전에 런칭이 되었습니다. (좀 됐습니다만)

 

Lambda는 serverless 서비스의 대표적인 예입니다. 사용자는 서버 없이도 계산 또는 프로세싱이 필요한 컴퓨팅 환경을 Lambda를 통해서 실행할 수가 있습니다. 서비스 내부적으로는 컴퓨팅 자원이 있지만, 사용자 측면에서는 CPU나 메모리를 잠깐 임대해서 사용하는 서비스 입니다. 장시간의 컴퓨팅이 필요없고, 순간순간 필요한 작업이라면 Lambda를 사용하는 것이 매우 효율적입니다. 그러나,  “프로세싱”의 종류에 따라서 On-Demand 인스턴스가 더 나을 때 도 있습니다. 과금 정책에서 사용할 메모리, 그리고 프로세싱에 걸리는 시간에 따라서 금액이 달라지기 때문에 상황에 따라서 판단해야 할 부분입니다.

 

클라우드의 특징은 사용한 만큼에 대해서 비용을 지불하는 것입니다. 사용하지 않는다면 그만큼의 비용을 아낄수가 있습니다. 이번 Lambda 가이드는 간단하게 EC2를 시작 또는 정지하는 스케줄링 하는 방법에 대해서 알아봅니다.

 

Lambda는 그 이외에도 S3에 이미지를 업로드 할 때 Event를 호출하여 섬네일을 만들거나, 동영상파일이 업로드 될때는 동영상을 인코딩하는 등의 AWS 서비스와 연동하여 사용할 수가 있습니다. 활용하기 나름입니다.

 

AWS Lambda의 과금 정책

가격 참고 URL : https://aws.amazon.com/ko/lambda/pricing/

 

  • 가이드 순서
  • Lambda 기본설정 (python을 위한)
  • EC2 정지 스케줄
  • EC2 시작 스케줄
  • EC2 모든 인스턴스 정지

 

Lambda 기본설정 (python을 위한)

 먼저 LambdaRole를 실행하기 위해서 Policy를 만들고 Role에 Policy를 attach 시키겠습니다.

 

[Services]에서 IAM으로 이동 후 Policies로 이동합니다. 상단에 [Create Policy]를 클릭하세요.

 

 

 

다음 화면에서는 [Create Your Own Policy] 옆에 [Select]를 클릭하면 됩니다.

 

[Policy Name]에는 LambdaPolicy를 입력하고 Policy Document에 아래와 같은 EC2 컨트롤을 입력하세요. 아래 Policy는 단순 EC2의 리스트와 시작 정지가 가능한 권한을 주는 것이며, 만일 Lambda에서 다른 AWS 서비스를 활용해야 한다면 그에 합당한 Policy를 줘야합니다. 여기에서는 EC2의 시작/정지만을 수행할 예정이므로 아래와 같은 정책을 입력하였습니다. [Create Policy]를 클릭하세요.

 

 

 

이제 [Policies] 위에 있는 [Roles]로 이동하여 LambdaRole을 만든 후에 방금 만든 LambdaPolicy를 attach 시키겠습니다.

 

 

 

[Create New Role]을 클릭하고 Role 이름을 입력하고 [Next Step]을 클릭하세요.

 

 

 

[AWS Lambda] 옆에 [Select] 선택합니다.

 

014-01

Filter에 Lambda를 클릭하고 위에서 생성한 LambdaPolicy에 체크를 하고 [Next Step]을 누릅니다.

 

015-01

다음창에서는 [Create Role] 을 누르면 생성이 완료되니다.

생성된 후 [Roles]에서 LambdaRole 을 클릭하고 [Permissions]를 확인하면 아래와 같이 “LambdaPolicy”가 Attach 된 상황을 볼수가 있습니다.

016-01

 

위에서 생성한 LambdaRole은 다음에 Lambda function을 생성 후에 실행할 Role로 지정할 때 사용할 예정입니다.

[Services]에서 [Lambda]를 선택 합니다. 다음 화면에서는 “Get Started Now” 를 선택하시면 됩니다. 아래와 같습니다.

001-1

 

 

 

002-1

[Select Blueprint]에서는 각종 프로그래밍의 예제를 볼수가 있습니다. 아래 그림에서 “Python 2.7”을 선택하시고 “Skip”을 선택합니다.

003-1

[Configure Triggers]에서는 어디로부터 이벤트를 받을지를 선택하는 것입니다.

026

위에서부터 API Gateway는 API Gateway에서 만든 URL을 호출하여 Lambda를 실행하는 것입니다. API Gateway에서는 GET 메소드에 대한 설정값으로 Lambda Function을 선택하고 만든  Lambda Function인 MyLambdaFunction을 지정하여 호출하면 됩니다.

api-gateway

 

또는 아래와 같이 만든 test api를 지정 한 후 resource에는 파라메터 값과 Method로는 GET이나 상황에 따라서 필요한 메소드를 넣으시면 됩니다. Security는 IAM 계정의 Security Credentail 키를 만들어서 특정계정만 실행하거나, 아니면 Anyone이 호출할수 있도록 Open을 하거나, 별도의 Access 키를 필요로하는 Access key open을 선택합니다. IAM 계정을 선택하는 것을 추천합니다.

api-gateway2

CloudWatch Events – Schedule은 Cron을 이용하여 정해놓은 시간 또는 매 시/분과 매일 실행한 것 처럼 일정 패넡으로 Lambda를 실행합니다. 여기에서 사용하는 이 방법으로 실행하는 방법으로 설명드릴 것입니다. 아래 그림은 월요일부터 금요일까지만 17시에 실행하게 만든 크론입니다. 이 시간은 UTC 기준이므로 한국시각으로 실행하기 위해서는 9시간을 빼야합니다. 만일 아침 10 시에 실행해야 된다면 설정을 cron(0 1 ? * MON-FRI *) 로 설정해야 합니다. 클론 설정에 관해서는 아래의 URL을 참고하시면 좋습니다.

http://docs.aws.amazon.com/lambda/latest/dg/tutorial-scheduled-events-schedule-expressions.html

schedule

CloudWatch Logs는 CloudWatch Log의 Log Group에 있는 특정 string 패턴을 입력하여 string패턴이 발생하면 Lambda를 호출하는 것입니다. CloudWatch Logs에 저장되는 기록을 참고하시면 됩니다. VPC Logs를 남긴다면 이를 기반으로 테스트 해볼수가 있습니다. 아래 그림을 참고하세요.

cloudwatch-log

 

그외에 DynamoDB는 DynamoDB에 생성된 table을 선택한 후 배치 사이즈를 선택합니다. 배치사이즈는 Lambda가 호출되었을때, DynamoDB의 테이블을 탐색하여 읽을 테이블의 사이즈를 지정해 주면되며 1 ~ 10,000까지 설정할수가 있습니다. 시작 포인트는 Latest와 Trim horizon중에 선택하시면 됩니다. Lambda 가 읽기를 시작할 스트림의 위치를 지정하면 됩니다. DynamoDB에도 마찬가지로 적용하면 됩니다.

dynamodb

Kinesis는 DynamoDB와 유사하게 생성된 데이터를 받는 Kinesis Stream을 선택하시고, 배치사이즈와 스타팅 포인트를 설정해주시면 됩니다.

S3는 S3의 Event를 설정하거나, 여기에서 선택한 버킷과 이벤트 타입(예를들면, 삭제나 업로드 같은 이벤트)에 따라서 Lambda를 실행할 수 있습니다. S3에 업로드 된, 이미지 파일의 섬네일이나 동영상을 인코딩 하는 경우에 매우 좋습니다. 설정은 버킷을 설정하고, 폴더와 파일의 확장자까지 지정하여 설정합니다. S3에서 설정하는 그림은 아래에 나와있습니다. S3의 버킷의 Properties를 선택하시고 아래와 같이 [Events]로 가시면 아래와 같이 설정이 가능합니다. 아래의 그림의 해당 버킷의 images/ 폴더에 있는  jpg파일이 put Event를 발생하면 Lambda를 호출하는 것입니다.

s3

 

또는 아래와 같이 Lambda에서 버킷/이벤트 타입과 위 그림에서와 같이 prefix/suffix를 입력하시고 생성하면 S3 이벤트로 Lambda를 호출합니다.

s3too

 

 

SNS는 SNS 토픽에 등록된 토픽중 하나를 선택하시면 됩니다. 해당 토픽에서 이벤트가 발생되면 Lambda 를 호출합니다.  CloudWatch와 해당 토픽이 연동되어 있거나 하면 Lambda가 수시로 호출되기 때문에 주의가 필요합니다.

sns

 

이제 원래 하려던 설정은  CloudWatch Events -Schdule이므로 아래 월요일부터 금요일까지 매일03시에 실행하도록 설정하였습니다. 12시로 설정했으나 UTC시각이므로 12시에서 9시간을 빼야 UTC 시각이 나옵니다.

 

every03hour

[Next]를 누릅니다. 다음화면에서는 “Function” 이름을 넣어주세요. “Runtime”에는 Python 2.7을 선택하세요.

005

 

코드는 일단 놔두시고, 아래쪽으로 스크롤을 이동하여 “Handler”는 기본으로 놔두시면 됩니다.

Role은 위에서 만드신 Role을 사용할 것이기 때문에 “Choose an existing role”을 선택하고 “Existing role”에서 “LambdaRole”을 선택합니다. 메모리는 기본으로 128로 놔두시고 실행시간을 10초로만 변경하니다. VPC는 사용하지 않을 것이기 때문에 “No VPC”를 선택하세요. 이제 [Next]를 누른 후 입력한 값이 잘 입력되었는지 확인 후 [Create Function]을 입력합니다.

006

 

다음 화면에서는 코드를 입력해야 하므로 [Code]로 이동하세요.

 

008-01

기본으로 나온 코드는 모드 삭제하시고, 아래의 코드를 입력하시길 바랍니다.

아래 코드의 원본은 아래의 URL에서 찾을 수 있으며, 더 아래쪽 코드는 원본 코드를 심플하게 수정한 코드입니다.

https://gist.github.com/pquery/1364b76cd3407e1bf61c27c13ed68a8e

이 코드는 EC2인스턴스의 Tag를 검색하여 Tag Key에 AutoStop이 있고 그 Value가 True이면 정지 시킵니다.

 

 

import boto3

def lambda_handler(event, context):

    # Use the filter() method of the instances collection to retrieve
    # all running EC2 instances.

    ec2 = boto3.resource('ec2')
    filters = [{
            'Name': 'tag:AutoStop',
            'Values': ['True']
        },
        {
            'Name': 'instance-state-name',
            'Values': ['running']
        }
    ]
    instances = ec2.instances.filter(Filters=filters)
    RunningInstances = [instance.id for instance in instances]
    if len(RunningInstances) > 0:
        #perform the shutdown
        shuttingDown = ec2.instances.filter(InstanceIds=RunningInstances).stop()
        print shuttingDown
    else:
        print "Nothing to see here"

 

아래 코드는 EC2를 시작하는 코드입니다. 태그에는 AutoStart Key와 Value로는 True가 설정되어 있어야 하니다.

 

import boto3

def lambda_handler(event, context):
    ec2 = boto3.resource('ec2')
    filters = [{
            'Name': 'tag:AutoStart',
            'Values': ['True']
        },
        {
            'Name': 'instance-state-name',
            'Values': ['stopped']
        }
    ]
    instances = ec2.instances.filter(Filters=filters)
    StoppedInstances = [instance.id for instance in instances]
    if len(StoppedInstances) > 0:
        #perform the shutdown
        StartInstances = ec2.instances.filter(InstanceIds=StoppedInstances).stop()
        print StartInstances
    else:
        print "Nothing to see here"

 

또한, Tag 설정에 관계없이 모든 EC2 인스턴스를 정지하는 코드입니다.

 

import boto3

def lambda_handler(event, context):
    ec2 = boto3.resource('ec2')
    instances = ec2.instances.all()
    RunningInstances = [instance.id for instance in instances]

    if len(RunningInstances) > 0:
        #perform the shutdown
        StartInstances = ec2.instances.filter(InstanceIds=RunningInstances).stop()
        print StartInstances
    else:
        print "Nothing to see here"

 

위 코드를 각각 Lambda function으로 EC2Start, EC2Stop, EC2AllStop 으로 생성하여 실행하면 됩니다.

 

EC2인스턴스의  Tags 규칙은 아래와 같이 설정하면 됩니다. 먼저 [EC2] 서비스로 이동 후 [Instances]로 이동하세요. 이동 후 인스턴스를 선택하시고, 하단의 [Tags]를 클릭하세요.

021-01

 

[Tags]에서 [Add/Edit Tags] 를 클릭하신 후 [Create Tag]를 2번 클릭하여 아래와 같이 2개의 Tag를 추가하면 됩니다. [Save]를 클릭하여 저장하면 됩니다.

022

 

위와같이 자동으로 시작 및 정지를 위해서 Tag를 추가하시면 됩니다. 만일 Tag도 싫고 그냥 떠 있는 인스턴스를 모두 정지시킬 생각이라면 모두 정지시키는 위에 소스를 Lambda Function으로 만드신 후에 원하시는 날짜와 시간으로 스케줄을 걸어서 모두 다 정지 시킬수가 있습니다.

 

Lambda Function을 수동으로 시험해 볼수도 있습니다. Function의 [Code]로 이동 후 상단의 [Save and test]를 누르면 저장하고 실행합니다. 또는 [Save]를 하고 [Test]를 눌러도 동일한 동작을 하게됩니다.

023

 

 

024

 

실행 후 아래와 같이 input Directonary가 나오면 무시하고[Save and test]를 누르시면 됩니다. 지우셔도 상관없습니다. 어차피 Context로부터 입력을 받아서 처리하지 않기 때문에 의미는 없습니다.

주의사항) Python은 indent에 민감하므로 에러가 날 경우에는 indent에 주의해야 합니다.

 

위에 생성한 Function에 대한 설정을 완료한 후 실행을 확인하려면 Monitoring을 확인하시면 됩니다. 결과는 실행한 횟수와 에러 실행 시간을 확인할 수가 있습니다. 해당 지표를 클릭하면 CloudWatch로 이동하여 지표를 확인할 수가 있습니다.

 

025

 

지금까지 AWS Lambda의 간단한 사용 방법에 대해서 가이드 하였습니다.

읽어주셔서 감사합니다.