フォーム読み込み中
共通プラットフォーム開発本部の宮田銀河 (入社3年目) です。
本記事では、定期実行するLambdaをAWS Cloud Development Kit (CDK) でデプロイする(Docker imageを使用)方法を紹介します。CDKでは、クラウドリソースの構成をPythonやTypescriptなどのプログラミング言語で記述できます。
また、Docker imageを使用することで、Lambda上で本来使えないnmapなどのツールを使うことができます。AWS CDKを使ってみたい方、CDKを使ってLambdaをデプロイしたい方に向けた記事です。
使用した技術はAWS CDK, Lambda, EventBridge, IAM, Dockerです。
本記事で作成するシステム構成図を下図に示します。
開発者はローカルのPCでcdk deployとコマンドを実行するだけで、AWS環境にリソースをデプロイすることができます。
Cloud Development Kitの略です。 CDKを簡単に説明すると、クラウドリソースの構成をPythonやTypescriptなどのプログラミング言語で記述できるというものです。Python大好きの私からすると、yamlやjsonでリソースを定義しなくて良いという嬉しさがあります。cdk depoyとコマンドを実行するだけで、Pythonファイルで定義したリソースを作成できます。CloudFormationのyamlファイルは書かなくて良いのです。実際はCDKの裏でCloudFormationが利用されています。詳細は公式ドキュメントをご覧ください。
CDKを初めて使用する場合は、セットアップのために以下のコマンドを実行する必要があります
npm install -g aws-cdk
cdk bootstrap
1行目のコマンドにより、aws-cdkをインストールします。2行目のコマンドにより、CloudFormation (CDKが裏で利用している) を使うためのS3 バケットやIAM Role等を作成します。この2行のコマンドを実行するだけで、CDKを使ったリソースのデプロイが可能になります。
をfoo_stack.pyとしてfooディレクトリ配下に配置します。LambdaはDocker imageを使用します。
from aws_cdk import (
aws_events as events,
aws_lambda as lambda_,
aws_iam as aws_iam,
aws_events_targets as targets,
Duration,
Stack,
)
from constructs import Construct
import os
from dotenv import load_dotenv
load_dotenv()
class FooStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
# 1. IAM poloicy (for Lambda Function)
lambdaRole = aws_iam.Role(
self,
"lambdaRole",
role_name="foo-lambda-role",
assumed_by=aws_iam.ServicePrincipal("lambda.amazonaws.com"),
)
lambdaRole.add_managed_policy(aws_iam.ManagedPolicy.from_aws_managed_policy_name("AWSLambdaExecute"))
lambdaRole.add_managed_policy(
aws_iam.ManagedPolicy.from_aws_managed_policy_name("追加したいManagedのRoleがあれば")
)
# 2. lambda configuration
lambdaFn = lambda_.DockerImageFunction(
self,
"FooFunction", # リソース名
timeout=Duration.seconds(300),
code=lambda_.DockerImageCode.from_image_asset("lambda/"),
role=lambdaRole,
retry_attempts=0,
environment={
"Foo": os.environ["Foo"],
"Bar": os.environ["Bar"],
},
)
# 3. cron configuration
rule = events.Rule(
self,
"Rule",
schedule=events.Schedule.cron(minute="0", hour="*/8", month="*", week_day="MON-FRI", year="*"),
)
rule.add_target(targets.LambdaFunction(lambdaFn))
上記のコードを一部解説します。
Lambda用のDockerfileは以下です。Dockerを使用した経緯を説明すると、元々Lambda上でnmapを使いたかったのですが、AWSが使用しているデフォルトのLambda環境にはnmapがインストールされてませんでした。そのため、AWSが用意しているLambdaのイメージにnmapのインストールを実行して、そのイメージを使う方針にしました。nmapの他に使用したいツール等あればこの段階でインストールしましょう。
FROM public.ecr.aws/lambda/python:3.8
COPY requirements.txt ${LAMBDA_TASK_ROOT}
RUN pip3 install -r requirements.txt --target "${LAMBDA_TASK_ROOT}" && yum install -y nmap
COPY . ${LAMBDA_TASK_ROOT}
CMD [ "foo.handler" ]
上記のDockerfileをlamba/に配置します。ディレクトリの構成は以下です。
.
├── app.py
├── lambda
│ ├── Dockerfile
│ ├── foo.py # lambdaで実行したいコード
│ ├── requirements.txt # 使用するライブラリ
├── foo
│ ├── __init__.py
│ └── foo_stack.py
後はローカルのPCでcdk deployとコマンドを実行すれば、foo_stack.pyに定義したLambdaやIAM Role等がデプロイされます (便利)。
ここでは遭遇した問題を2つまとめました。
1. Pythonで特定のライブラリを使用するために、Lambda Layerを作成する必要があった
Lambda上でrequestsなどのPythonのライブラリを使用するためには、使いたいライブラリをzipしてLambda Layerを作成した後に、Lambdaにアタッチしなければいけません。そのため以下のようなコマンドを実行して、作成したzipファイルをAWSにアップロードして、Lambda layerを作成していました (少し手間だった
cd lambda
pip install -r requirements.txt -t ./python
zip -r layer.zip python/
→対処法: Docker imageにPythonライブラリを内包することにより解決しました。
2. ローカルPCでdockerを起動しないとエラーが発生した
dockerを起動しない状態でcdk deployを実行すると、以下のログが出力されます。
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
→対処法: dockerを起動した状態でcdk deployを実行する (他にも良いやり方はありそうです。暫定対応です)。
今の状態だとローカルPCでdockerを起動していなければcdk deployできません。新しく開発メンバーが入った時には、ローカルのPCにcdk等をインストールしなければいけません。この手間を省くためにも、リソースのデプロイまでを自動化したいと考えています。具体的にはAWS CodePiplineを使用して実現する予定です。開発者がGitHubやAWS CodeCommitにコードをpushしたら、Code Deploy上でcdk deployを実行しリソースがデプロイされる構成を考えています。
本記事では、AWSのCDKを使ってLambdaをデプロイする方法を紹介しました。開発者は必要なDockerfileとCDKのコードを用意して、cdk deployを実行するだけで、リソースのデプロイが可能になります。
AWS CDKを使ってみたい方、CDKを使ってLambdaをデプロイしたい方の参考になれば幸いです。
この記事を読んで興味を持っていただいた学生・エンジニアの方は、ぜひ当社の採用に応募して頂けると嬉しいです。
常に進化し続けるソフトバンクを楽しみながら
そんな一人一人の挑戦が会社の未来を創ります
条件に該当するページがございません