インフラ

【AWS】CloudFormationでLambdaを作ってみよう!

cloudformation-lambda

こんばんは!光です。

大手グローバル企業でWebエンジニアをやっています。

Webエンジニアを目指してプログラミングを勉強している初心者の方向けに情報を発信しています。

経歴や実績はこちら

システム開発のお仕事の依頼もお待ちしております。

お問い合わせページTwitterのDMからお気軽にお問い合わせください!

今回はこのようなご要望をいただきました。

CloudFormationでLambdaを作りたい!

CloudFormationは学習コストが高いのですが、使えるようになっておきたいですね。

そこで今回はこちらについて解説していきます!

ディレクトリ構成

ディレクトリ構成はこんな感じです。

cfn
├── log_rotate
    ├── lambda_function.py
    ├── lambda_function.zip
    └── master.yaml

CloudWatchLogsのログをS3にアーカイブするLambdaの土台にしたのでlog_rotateというディレクトリ名になっています。

lambda_function.py:Lambdaで動かす関数を作成

まずはLambdaで動かす関数を作成します。

お試し用なのでデフォルトのJSONを返す関数です。

import json

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

lambda_function.zip:Lambdaへデプロイするzipファイルの作成

lambda_function.pyを圧縮してzip形式にしておきます。

$ zip lambda_function lambda_function.py

master.yaml:CloudFormationのテンプレートを作成

CloudFormationでLambdaとLambdaを実行するIAMロールを作成します。

ディレクトリ構成によってS3Keyは書き換えてください。

Lambdaを実行するだけであればPolicies以下の記述は不要です。

AWSTemplateFormatVersion: 2010-09-09

# メタデータ
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:

      - Label:
          default: Common Configuration
        Parameters:
          - BucketName

# パラメータ
Parameters:

  # テンプレートを配置するバケット
  BucketName:
    Type: String

# リソース
Resources:

  Lambda:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        S3Bucket: !Ref BucketName
        S3Key: cfn/log_rotate/lambda_function.zip
      FunctionName: !Sub ${AWS::StackName}-function
      Handler: lambda_function.lambda_handler
      Role: !GetAtt
        - LambdaExecutionRole
        - Arn
      Runtime: python3.8

  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${AWS::StackName}-function-execution-role
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: !Sub ${AWS::StackName}-function-policy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Resource: "*"
                Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - logs:CreateExportTask
                  - s3:GetBucketAcl
                  - s3:PutObject

CloudFormationでテンプレートを読み込む

あとはこれらのファイルをS3に配置してCloudFormationでmaster.yamlを読み込んでください。

私はcfnディレクトリごとS3に配置したのでmaster.yamlのURLは

https://xxxxxx.s3-ap-northeast-1.amazonaws.com/cfn/log_rotate/master.yaml

こんな感じでした。

CloudFormationでS3バケット名を指定することになりますが、このURLのxxxxxx部分を指定してあげれば大丈夫です。

あとがき

CloudFormationで作るのめんどくさいな〜と思いながらやってみたのですが、Lambdaって結構簡単に作れるんですね。

VPC周りを構築しなくても済む分、EC2よりも楽な気がします。

CloudFormation初心者でも触りやすいと思います!