Closed10
Lambdaにコンテナ形式でデプロイする
参考になりそうなサイト
1. プロジェクトディレクトリ作成
mkdir sample-ecr-lambda
cd sample-ecr-lambda
2. リージョンとアカウントIDを環境変数にセット
REGION="ap-northeast-1"
ACCOUNTID=$(aws sts get-caller-identity --output text --query Account)
3. pythonファイル作成
touch app.py
app.py
import json
def handler(event, context):
return {
"statusCode": 200,
"body": json.dumps(
{
"message": "hello world",
}
),
}
touch Dockerfile
パターン1
FROM public.ecr.aws/lambda/python:3.8
COPY app.py ./
CMD ["app.handler"]
パターン2
FROM public.ecr.aws/lambda/python:3.8 as build
RUN yum install -y unzip && \
curl -SL https://chromedriver.storage.googleapis.com/86.0.4240.22/chromedriver_linux64.zip > /tmp/chromedriver.zip && \
curl -SL https://github.com/adieuadieu/serverless-chrome/releases/download/v1.0.0-57/stable-headless-chromium-amazonlinux-2.zip > /tmp/headless-chromium.zip && \
unzip /tmp/chromedriver.zip -d /opt/ && \
unzip /tmp/headless-chromium.zip -d /opt/
FROM public.ecr.aws/lambda/python:3.8
# driverのバイナリ等を /opt 配下にコピー(lambdaでの処理実行時に /tmp にコピーする)
COPY --from=build /opt/headless-chromium /opt/
COPY --from=build /opt/chromedriver /opt/
RUN yum install -y https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
RUN pip install selenium
# lambda実行に必要なコード等
COPY app.py requirements.txt ./
RUN python3.8 -m pip install --upgrade pip
RUN pip install -r requirements.txt
ENV DISPLAY=:0.0
CMD ["app.lambda_handler"]
パターン3
FROM public.ecr.aws/lambda/python:3.7
RUN pip install --upgrade pip && \
pip install -t ./ selenium
COPY app.py ./
COPY bin/chromedriver /var/task/bin/
COPY bin/headless-chromium /var/task/bin/
CMD ["app.handler"]
docker build -t func1 .
# func1があるか確認
ls func1
docker images
4. テスト
docker run --rm -p 9000:8080 func1:latest
# 別のターミナルから
curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
# docker runしたターミナルで
Ctrl+C
5. ECRリポジトリ作成・イメージPUSH
# ECRリポジトリ作成CFn
touch createECRRepository.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: Create ECR Stack Test
Resources:
########################################################
### ECR Repository
########################################################
TestEcrPoc:
Type: AWS::ECR::Repository
Properties:
RepositoryName: func1
aws cloudformation create-stack --stack-name tempecrrepo --template-body file://createECRRepository.yaml --region ${REGION}
# 認証
aws ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin ${ACCOUNTID}.dkr.ecr.${REGION}.amazonaws.com
# イメージPUSH
docker push ${ACCOUNTID}.dkr.ecr.${REGION}.amazonaws.com/func1:latest
6. Lambda作成
# Lambda作るCFn
touch createLambda.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: Create ECR Stack Test
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
# CFnのパラメータに使う文字列を生成
DIGEST=$(aws ecr list-images --repository-name func1 --region ${REGION} --out text --query 'imageIds[?imageTag==`latest`].imageDigest')
IMAGEURI=${ACCOUNTID}.dkr.ecr.${REGION}.amazonaws.com/func1@${DIGEST}
# Lambda作成。IAM作るのでcapabilities指定
aws cloudformation create-stack --stack-name tempecrlambda \
--template-body file://createLambda.yaml \
--region ${REGION} \
--parameters \
ParameterKey=LambdaFunctionName,ParameterValue=func1-container \
ParameterKey=ImageUri,ParameterValue=${IMAGEURI} \
--capabilities CAPABILITY_NAMED_IAM
# 実行
aws lambda invoke --function-name func1-container --region ${REGION} output ; cat output
7. 後処理
# Lambda削除
aws cloudformation delete-stack --stack-name tempecrlambda --region ${REGION}
# ECR上イメージ削除
aws ecr batch-delete-image --repository-name func1 --region ${REGION} --image-ids imageDigest=${DIGEST}
# ECRリポジトリ削除
aws cloudformation delete-stack --stack-name tempecrrepo --region ${REGION}
# Dockerイメージを確認して、削除
docker images | grep func1
docker rmi <<IMAGENAME>>
0. dockerインストール
docker --version
sudo yum install -y docker
# Docker がインストールされていることを確認
docker --version
sudo service docker start
sudo docker info
0. S3からコピー
aws s3 cp s3://work/lambda_function.zip .
unzip lambda_function.zip
0. ライブラリインストール
pip install -r requirements.txt
selenumのインストール
dockerを使用しなくても、良さそうなので一旦クローズ。
このスクラップは2023/01/04にクローズされました