CloudFormationを使用してAWS Lambda関数を作成してみよう!

本記事では「CloudFormationを使用してAWS Lambda関数を作成してみよう!」と題して、CloudFormationを使用したLambda関数のプロビジョニング方法について解説していきます。

CloudFormationとは

CloudFormationとは、AWSリソースを自動でプロビジョニングすることができるサービスです。
AWSのシステム構成をコード化したテキストファイル(テンプレート)を作成することで、テンプレートに基づいたシステム構成を自動でプロビジョニング可能となります。

よく使うシステム構成をテンプレート化しておくことで、環境作成にかかる時間を大幅に短縮することが可能となります。また、複数のAWSアカウントで同様のシステムを構成する場合にも便利なサービスとなっております。

実際にやってみよう

今回はLambda関数の作成に加えて、Lambda関数の実行に必要なIAMロールの作成を行います。

以下の流れで手順を実施致します。

  1. テンプレートファイル(YAML形式)の作成
  2. CloudFormationスタックの作成
  3. 作成されたリソースの確認

テンプレートファイル(YAML形式)の作成

今回作成したコードの内容については、以下の通りとなります。

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  LambdaFunctionName:
    Type: String
  IAMRoleforLambda:
    Type: String
Resources:
  FunctionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Ref IAMRoleforLambda
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Policies:
        - PolicyName: putlog-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}:*" 
  TargetFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Ref LambdaFunctionName
      Role: !GetAtt FunctionRole.Arn
      Runtime: python3.10
      Handler: index.lambda_handler
      Code:
        ZipFile: !Sub |
          import json
          def lambda_handler(event, context):
              # TODO implement
              return {
                  'statusCode': 200,
                  'body': json.dumps('Hello from Lambda!Create${LambdaFunctionName}')
              }

コード内の各セクションの内容について解説します。

AWSTemplateFormatVersion
AWSTemplateFormatVersion: 2010-09-09

最新のテンプレート形式のバージョンを指定して下さい。

Parameters
Parameters:
  LambdaFunctionName:
    Type: String
  IAMRoleforLambda:
    Type: String

CloudFormationにてテンプレートを使用して実際にAWSリソースを作成する際に、「利用者が手動で指定するパラメータ」を定義して下さい。パラメータに入力された値は、組み込み関数の「Ref」や「Fn::Sub」を使用することで呼び出すことができます。

今回は、「Lambda関数の名前」や「IAMロールの名前」を利用者に手動で入力してもらう想定で、パラメータを定義しました。

Resources
Resources:
  FunctionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Ref IAMRoleforLambda
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Policies:
        - PolicyName: putlog-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}:*" 

Resourcesセクションについては、リソースタイプごとの構文がAWS公式ドキュメントに詳しく記載されておりますので、そちらを参照して、作成するリソースの構文の形式に合わせて記述して下さい。

AWS リソースおよびプロパティタイプのリファレンス - AWS CloudFormation

「Type: AWS::IAM::Role」で設定したプロパティの内容について以下で解説します。

■RoleName

「IAMロールの名前」を指定するプロパティとなります。

組み込み関数の「Ref」を使用して、利用者によって入力された値を呼び出し、「IAMロールの名前」に設定しています。

■AssumeRolePolicyDocument

IAMロールに設定する「信頼ポリシー」を指定するプロパティとなります。

Lambda関数がIAMロールを使用するため、Principalにlambda.amazonaws.comを設定しています。

■Policies

IAMロール直接記述するインラインポリシーの内容を記述します。今回は、CloudWatchLogsへのログの書き込み操作を許可するポリシー設定しています。

  TargetFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Ref LambdaFunctionName
      Role: !GetAtt FunctionRole.Arn
      Runtime: python3.10
      Handler: index.lambda_handler
      Code:
        ZipFile: !Sub |
          import json
          def lambda_handler(event, context):
              # TODO implement
              return {
                  'statusCode': 200,
                  'body': json.dumps('Hello from Lambda!Create${LambdaFunctionName}')
              }

「Type: AWS::Lambda::Function」で設定したプロパティの内容について以下で解説します。

■FunctionName

「Lambda関数の名前」を指定するプロパティとなります。

組み込み関数の「Ref」を使用して、利用者によって入力された値を呼び出し、「Lambda関数の名前」を設定しています。

■Role

Lambda関数に設定する「実行ロールのARN」を指定するプロパティとなります。「Fn::GetAtt」関数を使用することで、作成したリソースの属性値を取得することが可能となっており、IAMロールからは「ARN」や「ロールID」を取得することができます。対象のリソースごとに、取得できる属性値は異なりますので、こちらについても上で紹介したAWSの公式ドキュメントを参照してください。

■Runtime

「Lambda関数のRuntime」を設定します。今回は、python3.10を設定しています。

■Handler

「Handlerの名前」を設定します。今回は、index.lambda_handlerを設定しています。

■Code

「Lambda関数のコードの内容」を設定します。今回は、簡単なLambda関数のコードを記載します。

CloudFormationスタックの作成

作成したテンプレートファイルを元に実際にLambda関数の作成を行っていきます。

(1)AWSのマネージメントコンソールにログイン後、CloudFormationの画面に進みます。

(2)「スタックの作成」から「新しいリソースを使用」を選択します。

(3)「テンプレートファイルのアップロード」を選択し、「ファイルの選択」から前の手順で作成したテンプレートファイルを選択します。

(4)「スタックの名前」と各パラメータの設定をします。テンプレートファイル内のパラメータセクションで記述したパラメータについて、値の入力を求められます。

(5)以下のチェック項目にチェックを付け、「送信」を押下します。

(6)作成したスタックのイベント情報で「CREATE_COMPLETE」と表示されると完了です。

作成されたリソースの確認

AWSのマネージメントコンソールからLambdaの管理画面に進み、Lambda関数が作成されていることを確認して下さい。

また、作成されたLambda関数の実行ロールに、テンプレートファイルから作成したIAMロールが設定されていることを確認して下さい。

おわりに

今回は、CloudFormationを使用してAWS Lambda関数の作成を行いました。

作成したLambda関数やIAMロールは、CloudFormationのスタックを削除することで、まとめて削除することが可能となりますので、お気軽にお試し下さい。

執筆担当者プロフィール
内田 順也

内田 順也(日本ビジネスシステムズ株式会社)

プロフェッショナルサービス事業本部に所属。AWSに関連する運用支援業務を担当しております。 最近ではセキュリティ周りのAWSサービスの学習に力を入れてます!

担当記事一覧