0
0

LambdaをRで動かすlambdr

Posted at

はじめに

AWS LambdaをRで動かせるようにしたlambdrなるものを作った方がいらっしゃいました。

今回はこれを動かしてみました。

概要

  • LambdをRで動かせます
    • 非公式なので、利用は自己責任で

参考に、PHPでLambdaを動かす事例が公式で記事になっています。これと同様のものをRで作っています。

やってみた

環境

いつものCloud9です。t2.microでやりました。ストレージがギリギリです。他のものが入っているとエラーになりますので容量にはご注意ください。

コンテナ作成とPUSH

まずはコンテナをbuildします。

# プロジェクトディレクトリ作成
mkdir test-lambdr && cd test-lambdr

# 対象をPULL
docker pull public.ecr.aws/lambda/provided

# サンプル用のファイルを作成。コードは以下に
# https://github.com/mdneuzerling/lambdr#example
touch Dockerfile
touch runtime.R

# よく使う文字列を環境変数にセット
REGION="ap-northeast-1"
ACCOUNTID=$(aws sts get-caller-identity --output text --query Account)
IMAGENAME="test-lambdr"

# build 3分強。Cloud9デフォルト10GBだとカツカツ
docker build -t ${IMAGENAME} .

次にECRを作ります。

# ECRリポジトリ作成CFn
touch createECRRepository.yaml

ECRを作るCFnは以下になります

createECRRepository.yaml
AWSTemplateFormatVersion: "2010-09-09"

Parameters:
  RepositoryName:
    Type: String

Resources:
  TestEcrPoc:
    Type: AWS::ECR::Repository
    Properties:
      RepositoryName: !Ref RepositoryName

Outputs:    
  RepositoryUri:
    Value: !GetAtt TestEcrPoc.RepositoryUri

ECRを作って、先ほどのコンテナをPUSHします。

# ECRにレポジトリ作成
STACKNAME="create-ecrrepo-lambdr"
REPOSITORYNAME="test-lambdr-ecs"
aws cloudformation create-stack --stack-name ${STACKNAME} \
  --template-body file://createECRRepository.yaml \
  --region ${REGION} \
  --parameters \
    ParameterKey=RepositoryName,ParameterValue=${REPOSITORYNAME}

# イメージにタグ付与
TAGNAME=`aws cloudformation describe-stacks --stack-name ${STACKNAME} --query "Stacks[].Outputs[?OutputKey=='RepositoryUri'].[OutputValue]"  --output text`:latest
docker tag ${IMAGENAME}:latest ${TAGNAME}

# 認証
aws ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin ${ACCOUNTID}.dkr.ecr.${REGION}.amazonaws.com

# 作ったイメージをPUSH
docker push ${TAGNAME}

Lambdaを作る

昔の自分の記事を参考に作ってきます。

後で消しやすいように、LambdaもCFnで作ります。

# Lambda作るCFn
touch createLambda.yaml
createLambda.yaml
AWSTemplateFormatVersion: "2010-09-09"

Parameters:
  LambdaFunctionName:
    Type: String
  ImageUri:
    Type: String
    
Resources:
  ########################################################
  ### Log Group
  ########################################################
  FunctionLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/lambda/${LambdaFunctionName}"
      RetentionInDays: 3653

  ########################################################
  ### IAM Role
  ########################################################
  FunctionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "for-lambdafunction-${LambdaFunctionName}"
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: '/service-role/'
      Policies:
        # CloudWatch
        - PolicyName: write-cloudwatchlogs
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action: 
                  - 'logs:CreateLogStream'
                  - 'logs:PutLogEvents'
                Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${LambdaFunctionName}:*"    

  ########################################################
  ### Lambda Function
  ########################################################
  TargetFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Ref LambdaFunctionName
      Role: !GetAtt FunctionRole.Arn
      PackageType: Image
      Code:
        ImageUri: !Ref ImageUri

必要な文字列は変数に格納して、Lambdaを作ります。

DIGEST=$(aws ecr list-images --repository-name ${REPOSITORYNAME} --region ${REGION} --out text --query 'imageIds[?imageTag==`latest`].imageDigest')
IMAGEURI=`aws cloudformation describe-stacks --stack-name ${STACKNAME} --query "Stacks[].Outputs[?OutputKey=='RepositoryUri'].[OutputValue]"  --output text`@${DIGEST}
FUNCTIONNAME="func-lambdr"
STACKNAMEFUNCTION="create-func-lambdr"

aws cloudformation create-stack --stack-name ${STACKNAMEFUNCTION} \
  --template-body file://createLambda.yaml \
  --region ${REGION}  \
  --parameters \
    ParameterKey=LambdaFunctionName,ParameterValue=${FUNCTIONNAME} \
    ParameterKey=ImageUri,ParameterValue=${IMAGEURI} \
  --capabilities CAPABILITY_NAMED_IAM

実行

以下のようにして実行できます。

aws lambda invoke --function-name ${FUNCTIONNAME} \
  --cli-binary-format raw-in-base64-out --region ${REGION} \
  --payload '{"number": 11}' output ; cat output

おわりに

今回はlambdrを紹介しました。
Lambdaの動作については以下のページがわかりやすいです。

これをRで実装したのですから、作成者には頭が下がります…

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0