はじめに
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で実装したのですから、作成者には頭が下がります…