【AWS】CDKv2で環境構築　Lambda編

# はじめに
現在運用中の環境をテスト用として複製する際に`CDKv2`を用いて
コード化することになったのでその学びです。

[DynamoDB編はこちら](https://qiita.com/yamato1491038/items/f388afa3aa4f701321f5)
[Cognito編はこちら](https://qiita.com/yamato1491038/items/bbef1df21e54e22d36ca)
[apigateway編はこちら](https://qiita.com/yamato1491038/items/63fc91325c6f72464b49)
[StepFunctions編はこちら](https://qiita.com/yamato1491038/items/7393c910f70bf241ed62)


# 準備

このへんの記事でまずは環境設定
https://aws.amazon.com/jp/getting-started/guides/setup-cdk/

今回は`TypeScript`を用いて実装しました。

```
$ cdk init --language typescript
```

# ロール作成

まずはLambda用のRoleを作成します。
わざわざ作成しなくてもLambdaを動かすRoleは自動作成されますが、
今回はLambdaからS3やDynamoDBへアクセスするため作成が必要でした。

```typescript:/lib/main-stack.ts

import * as cdk from 'aws-cdk-lib';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as lambda from 'aws-cdk-lib/aws-lambda';

export class MainStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Lambda resource -------------------

    // Lambda用の基本的なログ書込みのIAMポリシー作成
    const lambda_basic_policy = new iam.ManagedPolicy(this, 'Lambda_basic_policy', {
      managedPolicyName: 'lambda_basic_policy',
      description: 'Lambda basic execution policy',
      statements: [
        new iam.PolicyStatement({
          effect: iam.Effect.ALLOW,
          actions: ['logs:*'],
          resources: ['arn:aws:logs:*:*:*'],
        }),
      ],
    });

    // ロール作成
    const sample_role = new iam.Role(this, 'Sample_role', {
      roleName: 'sample_role',
      assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
    });
    sample_role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonDynamoDBFullAccess'));
    sample_role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonS3FullAccess'));
    sample_role.addManagedPolicy(lambda_basic_policy);　// 先ほど作成したポリシーをアタッチ
  }
}

```

まずはLambda自身でポリシーを作成する方法です。
`iam.ManagedPolicy`で作成でき、
`statements`でjsonでの設定のようにポリシーを設定できます。

その次にroleを作成します。
`addManagedPolicy（）`でポリシーをアタッチしますが、
AWS管理のポリシーであれば`fromAwsManagedPolicyName('AmazonDynamoDBFullAccess')`で呼び出すことができます。

# 関数作成

```typescript:/lib/main-stack.ts

import * as cdk from 'aws-cdk-lib';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as lambda from 'aws-cdk-lib/aws-lambda';

export class MainStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Lambda resource -------------------

    // （中略）

    const sample_fn = new lambda.Function(this, 'sample_handler', {
      functionName: 'sample', //関数名
      runtime: lambda.Runtime.NODEJS_14_X;, // ランタイム設定
      code: lambda.Code.fromAsset('lambda'),
      handler: 'index.handler', // ハンドラー設定
      memorySize: 512, // メモリサイズ
      architecture: lambda.Architecture.ARM_64, // or lambda.Architecture.X86_64
      role: sample_role, // 先ほど作成したRole
      timeout: cdk.Duration.seconds(10), // タイムアウト設定
    });
  }
}

```

`code`について。
`lambda.Code.fromAsset('lambda')`はこのプロジェクトがあるフォルダの
ルートにあるLambdaフォルダの中身を全てZIP化しアップロードするとという動きです。

`code`、`handler`、`runtime`以外はオプションです。（デフォルト設定がある）

`timeout`では数値を指定するが、`CDK`内での数値などの指定方法が決まっているようで
　`cdk.Duration.seconds(10)`のように`CDK`にある`Duration`クラスを呼び出しています。これ以外でもさまざま`CDK`からクラスを呼び出し設定するシチュエーションがあります。
呼び出し方もドキュメントのプロパティのところをみると記載してあります！

# DynamoDB streamから呼び出すとき

```typescript:/lib/main-stack.ts

import * as cdk from 'aws-cdk-lib';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as lambda from 'aws-cdk-lib/aws-lambda';

export class MainStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Lambda resource -------------------

    // （中略）

    const sample_fn = new lambda.Function(this, 'sample_handler', {
      functionName: 'sample', //関数名
      runtime: lambda.Runtime.NODEJS_14_X;, // ランタイム設定
      code: lambda.Code.fromAsset('lambda'),
      handler: 'index.handler', // ハンドラー設定
      memorySize: 512, // メモリサイズ
      architecture: lambda.Architecture.ARM_64, // or lambda.Architecture.X86_64
      role: sample_role, // 先ほど作成したRole
      timeout: cdk.Duration.seconds(10), // タイムアウト設定
    });

    // DynamoDB stream設定
      sample_fn.addEventSource(new lambdaEvent.DynamoEventSource(sample_table, {
      startingPosition: lambda.StartingPosition.LATEST,
      batchSize: 1,
    }));
  }
}

```

関数に対して`addEventSource()`でトリガーを設定し、
`lambdaEvent.DynamoEventSource()`でstreamをONしたテーブルを指定し、
パラメータを設定する。


# ドキュメント
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html