LoginSignup
1
1

More than 3 years have passed since last update.

AWS Lambda を CloudFormation でサクッと作って awscli から実行する

Last updated at Posted at 2019-11-21

概要

要旨

CloudFormation で Lambda を作って、Lambda を awscli から実行(invoke)する。

やりたいこと

  • Lambda Function を CloudFormation で作成、削除したい
  • CloudFormation のテンプレートに関数を埋め込んで一つのファイルだけで管理したい
    • pros: テンプレートに埋め込むとs3へアップロードしておく等の事前準備が不要になる
    • cons: 標準モジュール以外を使用する場合はテンプレート埋め込みの方法は使えない
  • awscli から lambda を実行できれば十分
    • HTTP公開は認証やDDoS対策が面倒
    • HTTP公開やイベント登録はしない
      • HTTP公開はAPIの設定が必要になる

作業

前提

  • awscliがインストールされており、認証もされている
  • 以下のロールを持っている(もっと削れるかも)
    • AWSLambdaBasicExecutionRole
    • AWSLambdaFullAccess
  • Lambda内で標準モジュールしか使わない
  • 下記サンプルのランタイムは Python 3.7

ローカルファイルの用意

lambda.template.yamlを以下をコピペしてローカルに作りましょう。

lambda.template.yaml

lambda.template.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: access test
Resources:
  AccessTestLambda:
    Type: 'AWS::Lambda::Function'
    Properties:
      Code:
        ZipFile: |
          import json
          def lambda_handler(event, context):
              return {
                  'msg_const': "Hello, World !!",
                  'msg_from': event["msg"],
              }
      Description: access test lambda
      FunctionName: accessTest
      Handler: index.lambda_handler
      Role: !GetAtt 
        - LambdaExecutionRole
        - Arn
      Runtime: python3.7
  LambdaExecutionRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
  AccessTestLogGroup:
    Type: 'AWS::Logs::LogGroup'
    Properties:
      LogGroupName: /aws/lambda/accessTest
      RetentionInDays: 14

index.py

上記 yaml で CloudFormation のスタックを作ると、 AWS 内に以下の Python ファイルができます。
(yamlファイルだとpython部分のシンタックスハイライトがされないのでここに記載しただけで、作成する必要はありません)

index.py
import json
def lambda_handler(event, context):
    return {
        'msg_const': "Hello, World !!",
        'msg_from': event["msg"],
    }

CloudFormationでデプロイ

スタック作成

$ ls
lambda.template.yaml
$ aws cloudformation create-stack --template-body file://lambda.template.yaml --capabilities CAPABILITY_IAM --stack-name access-test-lambda
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:000000000000:stack/access-test-lambda/00000000-0000-0000-0000-000000000000"
}

以下のリソースが作成されます。
- Lambda Function
- ロール
- ロググループ

できたか確認

"StackStatus": "CREATE_COMPLETE"になっていれば作成できています。

$ aws cloudformation describe-stacks --stack-name access-test-lambda
{
    "Stacks": [
        {
            "StackId": "arn:aws:cloudformation:ap-northeast-1:000000000000:stack/access-test-lambda/00000000-0000-0000-0000-000000000000",
            "DriftInformation": {
                "StackDriftStatus": "NOT_CHECKED"
            },
            "Description": "access test",
            "Tags": [],
            "EnableTerminationProtection": false,
            "CreationTime": "2019-12-31T23:59:59.999Z",
            "Capabilities": [
                "CAPABILITY_IAM"
            ],
            "StackName": "access-test-lambda",
            "NotificationARNs": [],
            "StackStatus": "CREATE_COMPLETE",
            "DisableRollback": false,
            "RollbackConfiguration": {}
        }
    ]
}

スタック削除

$ aws cloudformation delete-stack --stack-name access-test-lambda

awscli から Lambda実行

aws lambda invokeで同期実行します。
result.jsonに結果が吐かれます。

$ echo "存在するドメイン"
$ aws lambda invoke --function-name "accessTest" --payload '{ "msg": "https://example.com" }' result.json
{
    "ExecutedVersion": "$LATEST",
    "StatusCode": 200
}
$ cat result.json
{"msg_const": "Hello, World !!", "msg_from": "https://example.com"}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1