CINXE.COM
AWS CDK で TypeScript Lambda をいい感じに管理するサンプルコード集 | Basicinc Enjoy Hacking!
<!DOCTYPE html><html lang="ja" data-scope-path="layouts/application"><head prefix="og: http://ogp.me/ns# article: http://ogp.me/ns/article#"><link crossorigin="" href="https://www.google-analytics.com/analytics.js" rel="preconnect" /><link rel="preload" href="/fonts/noto-sans-jp-v24-japanese-regular.woff2" as="font" type="font/woff2" crossorigin="anonymous"><link rel="preload" href="/fonts/noto-sans-jp-v24-japanese-700.woff2" as="font" type="font/woff2" crossorigin="anonymous"><!-- Global site tag (gtag.js) - Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id=UA-25666851-3"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-25666851-3'); </script> <link rel="stylesheet" media="all" href="/assets/ress-d1ba3a251927ab1f2bcc841c9a810109355bcb4260a522a0f76452fdc2fe6095.css" /><link rel="stylesheet" media="all" href="/assets/scopes/layouts/application-dda4ec688c139c8f29c39a2a795bcf4af04c4326643549a37f5d8843fffaebab.css" /><link rel="stylesheet" media="all" href="/assets/scopes/articles/show-37905516c06229c8fde10714e660fc48bc7b6ce7881755707db8b0327ceb5bf1.css" /><link rel="stylesheet" media="all" href="/assets/scopes/partials/_viewer-3a78a10250bb498047a06b71271b62ea949e304d25b9781c4450cf998aa2640c.css" /><link rel="stylesheet" media="all" href="/assets/scopes/layouts/_header-db87b54171cc020758ab7d1494677f8f6c2e9c93b453e896af82e4814eaacc7c.css" /><link rel="stylesheet" media="all" href="/assets/scopes/layouts/_breadcrumbs-744a099ab0b9eb5c4bd45215617e267c7d7c404ddddce8810eead5335512e637.css" /><link rel="stylesheet" media="all" href="/assets/scopes/layouts/_footer-a06961717440c6d0183c582c7f21768011f334d368f51b614eabc87bb17b3bbf.css" /><script src="/packs/application-02365dbc4dc28919eee1.js" defer="defer"></script><link href="/icon.png" rel="icon" type="image/png" /><link href="/apple-touch-icon.png" rel="apple-touch-icon" type="image/png" /><link href="/feed" rel="alternate" title="RSS2.0" type="application/rss+xml" /><title>AWS CDK で TypeScript Lambda をいい感じに管理するサンプルコード集 | Basicinc Enjoy Hacking!</title><meta name="csrf-param" content="authenticity_token" /> <meta name="csrf-token" content="23F4eQ4B+txlSsTnycZigkaSKuOI3keSVxrIWPCrvsLB7HNVRXlJ8d33KY91/8dcCVnATYjLVGnGyqoe4pJMMw==" /><meta content="width=device-width,initial-scale=1" name="viewport" /><meta content="AWS CDK で TypeScript Lambda をいい感じに管理するサンプルコード集 | Basicinc Enjoy Hacking!" property="og:title" /><meta content="article" property="og:type" /><meta content="2020-07-09T10:06:13+09:00" property="article:published_time" /><meta content="zaru" property="article:author" /><meta content="Technology" property="article:section" /><meta content="https://tech.basicinc.jp/articles/213" property="og:url" /><meta content="https://tech.basicinc.jp/assets/default_eyecatch-9e0d94e7defd5e124532d0b790a8f8cccfdffa0aed4581afa5f932cfec0b39a2.png" property="og:image" /><meta content="image/png" property="og:image:type" /><meta content="1200" property="og:image:width" /><meta content="630" property="og:image:height" /><meta content="弊社で AWS CDK を使って TypeScript Lambda 管理の運用が始まりました。運用に乗せるまでに試行錯誤して作った Lambda 管理サンプルコードをまとめておきます。 とりあえず TypeScript な Lambda Lambda 自体を TypeSc..." property="og:description" /><meta content="ja_JP" property="og:locale" /><meta content="summary" name="twitter:card" /><meta content="@zaru" name="twitter:creator" /></head><body><header data-scope-path="layouts/_header"><div class="header-contents"><a class="root-link" href="/"><svg class="site-logo"><use xlink:href="/assets/icons-5bbe775037b55281ef0bc50d30a51f69c7c3914d399c7107e37f0702d98ae8a2.svg#logo"></use></svg><div class="site-title">Enjoy Hacking!</div></a><div class="site-desc">Basicinc エンジニアブログ</div></div></header><nav data-scope-path="layouts/_breadcrumbs"><ul class="breadcrumbs" itemscope="itemscope" itemtype="https://schema.org/BreadcrumbList"><span class="pretext">% cat </span> <li itemprop="itemListElement" itemscope="itemscope" itemtype="https://schema.org/ListItem"><a itemprop="item" href="/"><span itemprop="name">~</span></a><meta itemprop="position" content="1" /></li>/<li class="current" itemprop="itemListElement" itemscope="itemscope" itemtype="https://schema.org/ListItem"><span itemprop="name">AWSCDKでTypeScriptLambdaをいい感じに管理するサンプルコード集.md</span><meta itemprop="item" content="https://tech.basicinc.jp/articles/213" /><meta itemprop="position" content="2" /></li></ul></nav><div data-scope-path="articles/show"><article class="article"><h1 class="article-title">AWS CDK で TypeScript Lambda をいい感じに管理するサンプルコード集</h1><div class="article-desc"><a class="article-author" href="/authors/1"><img class="article-author-avatar" src="https://tech.basicinc.jp/uploads/e868e5fb1e34b970ae7d8e04c454ff28.png" /><span class="article-author-name">zaru</span></a><div class="article-date-info"><time class="article-posted-date">Posted 2020-07-09</time></div></div><div class="article-body"><div data-scope-path="partials/_viewer"><p>弊社で AWS CDK を使って TypeScript Lambda 管理の運用が始まりました。運用に乗せるまでに試行錯誤して作った Lambda 管理サンプルコードをまとめておきます。</p> <h2>とりあえず TypeScript な Lambda</h2> <p>Lambda 自体を TypeScript で書きたいので <code>@aws-cdk/aws-lambda-nodejs</code> パッケージの <code>NodejsFunction</code> を使って Lambda を定義しています。これの便利なところはビルド含めて全部勝手にやってくれるところです。普通の JavaScript であれば <code>@aws-cdk/aws-lambda</code> パッケージの <code>Function</code> で同じように書くことができます。</p> <pre lang="typescript" class="highlight highlight-typescript"><span class="k">import</span> <span class="o">*</span> <span class="k">as</span> <span class="nx">core</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/core</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="p">{</span><span class="nx">NodejsFunction</span><span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/aws-lambda-nodejs</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="p">{</span><span class="nx">RemovalPolicy</span><span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/core</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="p">{</span><span class="nx">LogRetention</span><span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/aws-lambda</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="p">{</span><span class="nx">RetentionDays</span><span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/aws-logs</span><span class="dl">'</span><span class="p">;</span> <span class="k">export</span> <span class="kd">class</span> <span class="nx">SimpleLambdaStack</span> <span class="kd">extends</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Stack</span> <span class="p">{</span> <span class="kd">constructor</span><span class="p">(</span><span class="nx">scope</span><span class="p">:</span> <span class="nx">core</span><span class="p">.</span><span class="nx">App</span><span class="p">,</span> <span class="nx">id</span><span class="p">:</span> <span class="nx">string</span><span class="p">,</span> <span class="nx">props</span><span class="p">?:</span> <span class="nx">core</span><span class="p">.</span><span class="nx">StackProps</span><span class="p">)</span> <span class="p">{</span> <span class="k">super</span><span class="p">(</span><span class="nx">scope</span><span class="p">,</span> <span class="nx">id</span><span class="p">,</span> <span class="nx">props</span><span class="p">);</span> <span class="kd">const</span> <span class="nx">fn</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">NodejsFunction</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="dl">'</span><span class="s1">SimpleLambda</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span> <span class="na">entry</span><span class="p">:</span> <span class="dl">'</span><span class="s1">lambda/simple-lambda/index.ts</span><span class="dl">'</span><span class="p">,</span> <span class="na">currentVersionOptions</span><span class="p">:</span> <span class="p">{</span> <span class="na">removalPolicy</span><span class="p">:</span> <span class="nx">RemovalPolicy</span><span class="p">.</span><span class="nx">RETAIN</span><span class="p">,</span> <span class="p">},</span> <span class="na">memorySize</span><span class="p">:</span> <span class="mi">256</span><span class="p">,</span> <span class="na">timeout</span><span class="p">:</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Duration</span><span class="p">.</span><span class="nx">seconds</span><span class="p">(</span><span class="mi">180</span><span class="p">),</span> <span class="na">environment</span><span class="p">:</span> <span class="p">{</span> <span class="dl">'</span><span class="s1">TZ</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Asia/Tokyo</span><span class="dl">'</span><span class="p">,</span> <span class="p">},</span> <span class="p">});</span> <span class="c1">// CloudWatch Logs の保持期間を指定(デフォルトだと無期限)</span> <span class="k">new</span> <span class="nx">LogRetention</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="dl">'</span><span class="s1">SaveSessionLogRetention</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span> <span class="na">logGroupName</span><span class="p">:</span> <span class="s2">`/aws/lambda/</span><span class="p">${</span><span class="nx">fn</span><span class="p">.</span><span class="nx">functionName</span><span class="p">}</span><span class="s2">`</span><span class="p">,</span> <span class="na">retention</span><span class="p">:</span> <span class="nx">RetentionDays</span><span class="p">.</span><span class="nx">ONE_WEEK</span><span class="p">,</span> <span class="p">});</span> <span class="p">}</span> <span class="p">}</span> </pre> <p><code>currentVersionOptions</code> は Lambda のバージョンを残す設定です。常に LATEST だけで良いのであれば指定しなくて良いです。その他にメモリやタイムアウトなど Lambda のオプションは全て指定できます。</p> <p>1つ注意点としてはデフォルトで作成される CloudWatch Logs の保持期間は無期限になっています。ログが大量に出力される場合はコストが厳しくなるので要件に合わせて期間指定をした方が良いです。</p> <h2>npm パッケージを含めた Lambda</h2> <p>これは普通に Lambda のコードの中で <code>import </code> すれば自動でやってくれます。</p> <pre><code>npm install uuid </code></pre> <pre lang="typescript" class="highlight highlight-typescript"><span class="k">import</span> <span class="p">{</span><span class="nx">v4</span> <span class="k">as</span> <span class="nx">uuidv4</span><span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">uuid</span><span class="dl">'</span><span class="p">;</span> <span class="k">export</span> <span class="k">async</span> <span class="kd">function</span> <span class="nx">handler</span><span class="p">()</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">uuidv4</span><span class="p">());</span> <span class="p">}</span> </pre> <h2>既存のリソースに接続する Lambda</h2> <p>この例はすでに作ってある Kinesis Data Stream をトリガーとする Lambda の例です。</p> <p>AWS CDK では既存リソースの取得メソッドは <code>fromXXX</code> と from で始まるようになっているので、欲しいリソースパッケージのリファレンスを見ると大抵見つかります。リソースによって arn 指定するものもあれば他の識別子になっていることもあります。見つからない場合は AWS CDK GitHub リポジトリの Issue を検索すると、大体要望が上がっているので、それをウオッチするといいでしょう。</p> <pre lang="typescript" class="highlight highlight-typescript"><span class="k">import</span> <span class="o">*</span> <span class="k">as</span> <span class="nx">core</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/core</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="p">{</span><span class="nx">NodejsFunction</span><span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/aws-lambda-nodejs</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="p">{</span><span class="nx">RemovalPolicy</span><span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/core</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="o">*</span> <span class="k">as</span> <span class="nx">lambda</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/aws-lambda</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="o">*</span> <span class="k">as</span> <span class="nx">iam</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/aws-iam</span><span class="dl">'</span><span class="p">;</span> <span class="k">export</span> <span class="kd">class</span> <span class="nx">ExistsResourceLambdaStack</span> <span class="kd">extends</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Stack</span> <span class="p">{</span> <span class="kd">constructor</span><span class="p">(</span><span class="nx">scope</span><span class="p">:</span> <span class="nx">core</span><span class="p">.</span><span class="nx">App</span><span class="p">,</span> <span class="nx">id</span><span class="p">:</span> <span class="nx">string</span><span class="p">,</span> <span class="nx">props</span><span class="p">?:</span> <span class="nx">core</span><span class="p">.</span><span class="nx">StackProps</span><span class="p">)</span> <span class="p">{</span> <span class="k">super</span><span class="p">(</span><span class="nx">scope</span><span class="p">,</span> <span class="nx">id</span><span class="p">,</span> <span class="nx">props</span><span class="p">);</span> <span class="kd">const</span> <span class="nx">fn</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">NodejsFunction</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="dl">'</span><span class="s1">ExistsResourceLambda</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span> <span class="na">entry</span><span class="p">:</span> <span class="dl">'</span><span class="s1">lambda/exists-resource-lambda/index.ts</span><span class="dl">'</span><span class="p">,</span> <span class="na">currentVersionOptions</span><span class="p">:</span> <span class="p">{</span> <span class="na">removalPolicy</span><span class="p">:</span> <span class="nx">RemovalPolicy</span><span class="p">.</span><span class="nx">RETAIN</span><span class="p">,</span> <span class="p">},</span> <span class="p">});</span> <span class="c1">// Kinesis をトリガーにするために Lambda ポリシーを調整</span> <span class="nx">fn</span><span class="p">.</span><span class="nx">addToRolePolicy</span><span class="p">(</span><span class="k">new</span> <span class="nx">iam</span><span class="p">.</span><span class="nx">PolicyStatement</span><span class="p">({</span> <span class="na">resources</span><span class="p">:</span> <span class="p">[</span> <span class="dl">'</span><span class="s1">arn:aws:kinesis:ap-northeast-1:11111111:stream/sample</span><span class="dl">'</span><span class="p">,</span> <span class="p">],</span> <span class="na">actions</span><span class="p">:</span> <span class="p">[</span> <span class="dl">'</span><span class="s1">kinesis:DescribeStream</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">kinesis:DescribeStreamSummary</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">kinesis:GetRecords</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">kinesis:GetShardIterator</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">kinesis:ListShards</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">kinesis:ListStreams</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">kinesis:SubscribeToShard</span><span class="dl">'</span><span class="p">,</span> <span class="p">]}</span> <span class="p">));</span> <span class="kd">const</span> <span class="nx">kinesis</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">arn:aws:kinesis:ap-northeast-1:11111111:stream/sample</span><span class="dl">'</span><span class="p">;</span> <span class="nx">fn</span><span class="p">.</span><span class="nx">addEventSourceMapping</span><span class="p">(</span><span class="dl">'</span><span class="s1">KinesisDataTrigger</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span> <span class="na">eventSourceArn</span><span class="p">:</span> <span class="nx">kinesis</span><span class="p">,</span> <span class="na">batchSize</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span> <span class="na">startingPosition</span><span class="p">:</span> <span class="nx">lambda</span><span class="p">.</span><span class="nx">StartingPosition</span><span class="p">.</span><span class="nx">LATEST</span><span class="p">,</span> <span class="p">});</span> <span class="p">}</span> <span class="p">}</span> </pre> <p><code>addToRolePolicy</code> で Lambda に Kinesis にアクセスできる権限を追加します。そして <code>addEventSourceMapping</code> で指定リソースをイベントソースに設定します。</p> <h2>Lambda のエイリアスとバージョンを設定</h2> <p>一つの Lambda を開発やステージングとプロダクションなど複数の環境で使い分けるためにエイリアスを使いたくなる時があります。エイリアスを使うと各環境ごとの切り替えコストが低いのでオススメです。</p> <p>余談ですが、エイリアス単位で環境変数を持つことはできないので、そこは Lambda 関数内で自身のエリアスを取得して設定を切り替える必要があるところが面倒くさいです…。</p> <pre lang="typescript" class="highlight highlight-typescript"><span class="k">import</span> <span class="o">*</span> <span class="k">as</span> <span class="nx">core</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/core</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="p">{</span><span class="nx">NodejsFunction</span><span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/aws-lambda-nodejs</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="p">{</span><span class="nx">RemovalPolicy</span><span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/core</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="o">*</span> <span class="k">as</span> <span class="nx">lambda</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/aws-lambda</span><span class="dl">'</span><span class="p">;</span> <span class="k">export</span> <span class="kd">class</span> <span class="nx">AliasWithVersionLambdaStack</span> <span class="kd">extends</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Stack</span> <span class="p">{</span> <span class="kd">constructor</span><span class="p">(</span><span class="nx">scope</span><span class="p">:</span> <span class="nx">core</span><span class="p">.</span><span class="nx">App</span><span class="p">,</span> <span class="nx">id</span><span class="p">:</span> <span class="nx">string</span><span class="p">,</span> <span class="nx">props</span><span class="p">?:</span> <span class="nx">core</span><span class="p">.</span><span class="nx">StackProps</span><span class="p">)</span> <span class="p">{</span> <span class="k">super</span><span class="p">(</span><span class="nx">scope</span><span class="p">,</span> <span class="nx">id</span><span class="p">,</span> <span class="nx">props</span><span class="p">);</span> <span class="kd">const</span> <span class="nx">fn</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">NodejsFunction</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="dl">'</span><span class="s1">AliasWithVersionLambdaStack</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span> <span class="na">entry</span><span class="p">:</span> <span class="dl">'</span><span class="s1">lambda/alias-with-version-lambda/index.ts</span><span class="dl">'</span><span class="p">,</span> <span class="na">currentVersionOptions</span><span class="p">:</span> <span class="p">{</span> <span class="na">removalPolicy</span><span class="p">:</span> <span class="nx">RemovalPolicy</span><span class="p">.</span><span class="nx">RETAIN</span><span class="p">,</span> <span class="p">},</span> <span class="p">});</span> <span class="c1">// 最新バージョンを取得</span> <span class="kd">const</span> <span class="nx">currentVersion</span> <span class="o">=</span> <span class="nx">fn</span><span class="p">.</span><span class="nx">currentVersion</span><span class="p">;</span> <span class="c1">// development エイリアスは最新バージョンを指定</span> <span class="kd">const</span> <span class="nx">development</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">lambda</span><span class="p">.</span><span class="nx">Alias</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="dl">'</span><span class="s1">DevelopmentAlias</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span> <span class="na">aliasName</span><span class="p">:</span> <span class="dl">'</span><span class="s1">development</span><span class="dl">'</span><span class="p">,</span> <span class="na">version</span><span class="p">:</span> <span class="nx">currentVersion</span><span class="p">,</span> <span class="p">});</span> <span class="c1">// production エイリアスはバージョン1を指定</span> <span class="c1">// バージョンを切り替えたい場合はここを修正してデプロイする</span> <span class="kd">const</span> <span class="nx">prodVersion</span> <span class="o">=</span> <span class="nx">lambda</span><span class="p">.</span><span class="nx">Version</span><span class="p">.</span><span class="nx">fromVersionArn</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="dl">'</span><span class="s1">ProductionVersion</span><span class="dl">'</span><span class="p">,</span> <span class="s2">`</span><span class="p">${</span><span class="nx">fn</span><span class="p">.</span><span class="nx">functionArn</span><span class="p">}</span><span class="s2">:1`</span><span class="p">);</span> <span class="nx">prodVersion</span><span class="p">.</span><span class="nx">addAlias</span><span class="p">(</span><span class="dl">'</span><span class="s1">production</span><span class="dl">'</span><span class="p">);</span> <span class="c1">// もし production エイリアスに特定のリソーストリガーを設定したい場合はこちら</span> <span class="c1">// const prodAlias = lambda.Alias.fromAliasAttributes(this, 'ProductionAlias', {</span> <span class="c1">// aliasName: 'production',</span> <span class="c1">// aliasVersion: prodVersion</span> <span class="c1">// });</span> <span class="c1">// prodAlias.addEventSourceMapping('ProductionKinesisDataTrigger', {</span> <span class="c1">// eventSourceArn: 'arn:aws:kinesis:ap-northeast-1:11111111:stream/sample-prod',</span> <span class="c1">// batchSize: 10,</span> <span class="c1">// startingPosition: lambda.StartingPosition.LATEST</span> <span class="c1">// })</span> <span class="kd">const</span> <span class="nx">stgVersion</span> <span class="o">=</span> <span class="nx">lambda</span><span class="p">.</span><span class="nx">Version</span><span class="p">.</span><span class="nx">fromVersionArn</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="dl">'</span><span class="s1">StagingVersion</span><span class="dl">'</span><span class="p">,</span> <span class="s2">`</span><span class="p">${</span><span class="nx">fn</span><span class="p">.</span><span class="nx">functionArn</span><span class="p">}</span><span class="s2">:2`</span><span class="p">);</span> <span class="nx">stgVersion</span><span class="p">.</span><span class="nx">addAlias</span><span class="p">(</span><span class="dl">'</span><span class="s1">staging</span><span class="dl">'</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> </pre> <h2>Lambda@Edge をデプロイ</h2> <p>Lambda@Edge もいい感じにデプロイができます。この例だと新しく CloudFront と Origin の S3 を新しく作り、そこに Lambda を ORIGIN_REQUEST として設定をしています。S3 や ACM は既存のリソースが使えますが、CloudFront は現時点ではまだ使えません。必ず新規作成になります。</p> <pre lang="typescript" class="highlight highlight-typescript"><span class="k">import</span> <span class="o">*</span> <span class="k">as</span> <span class="nx">core</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/core</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="p">{</span><span class="nx">Bucket</span><span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/aws-s3</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="o">*</span> <span class="k">as</span> <span class="nx">cloudfront</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/aws-cloudfront</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="o">*</span> <span class="k">as</span> <span class="nx">certificatemanager</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/aws-certificatemanager</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="p">{</span><span class="nx">NodejsFunction</span><span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/aws-lambda-nodejs</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="p">{</span><span class="nx">RemovalPolicy</span><span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/core</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="o">*</span> <span class="k">as</span> <span class="nx">lambda</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/aws-lambda</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="o">*</span> <span class="k">as</span> <span class="nx">iam</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@aws-cdk/aws-iam</span><span class="dl">'</span><span class="p">;</span> <span class="k">export</span> <span class="kd">class</span> <span class="nx">CloudfrontLambdaEdgeStack</span> <span class="kd">extends</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Stack</span> <span class="p">{</span> <span class="kd">constructor</span><span class="p">(</span><span class="nx">scope</span><span class="p">:</span> <span class="nx">core</span><span class="p">.</span><span class="nx">App</span><span class="p">,</span> <span class="nx">id</span><span class="p">:</span> <span class="nx">string</span><span class="p">,</span> <span class="nx">props</span><span class="p">?:</span> <span class="nx">core</span><span class="p">.</span><span class="nx">StackProps</span><span class="p">)</span> <span class="p">{</span> <span class="k">super</span><span class="p">(</span><span class="nx">scope</span><span class="p">,</span> <span class="nx">id</span><span class="p">,</span> <span class="nx">props</span><span class="p">);</span> <span class="kd">const</span> <span class="nx">fn</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">NodejsFunction</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="dl">'</span><span class="s1">LambdaEdge</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span> <span class="na">entry</span><span class="p">:</span> <span class="dl">'</span><span class="s1">lambda/cloudfront-lambda-edge/index.ts</span><span class="dl">'</span><span class="p">,</span> <span class="na">currentVersionOptions</span><span class="p">:</span> <span class="p">{</span> <span class="na">removalPolicy</span><span class="p">:</span> <span class="nx">RemovalPolicy</span><span class="p">.</span><span class="nx">RETAIN</span><span class="p">,</span> <span class="p">},</span> <span class="na">role</span><span class="p">:</span> <span class="k">new</span> <span class="nx">iam</span><span class="p">.</span><span class="nx">Role</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="dl">'</span><span class="s1">AllowLambdaServiceToAssumeRole</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span> <span class="na">assumedBy</span><span class="p">:</span> <span class="k">new</span> <span class="nx">iam</span><span class="p">.</span><span class="nx">CompositePrincipal</span><span class="p">(</span> <span class="k">new</span> <span class="nx">iam</span><span class="p">.</span><span class="nx">ServicePrincipal</span><span class="p">(</span><span class="dl">'</span><span class="s1">lambda.amazonaws.com</span><span class="dl">'</span><span class="p">),</span> <span class="k">new</span> <span class="nx">iam</span><span class="p">.</span><span class="nx">ServicePrincipal</span><span class="p">(</span><span class="dl">'</span><span class="s1">edgelambda.amazonaws.com</span><span class="dl">'</span><span class="p">),</span> <span class="p">),</span> <span class="p">}),</span> <span class="p">});</span> <span class="kd">const</span> <span class="nx">fnVersion</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">lambda</span><span class="p">.</span><span class="nx">Version</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="dl">'</span><span class="s1">LambdaEdgeVersion</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span> <span class="na">lambda</span><span class="p">:</span> <span class="nx">fn</span><span class="p">,</span> <span class="p">});</span> <span class="kd">const</span> <span class="nx">sourceBucket</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Bucket</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="dl">'</span><span class="s1">ZaruCDKBucket</span><span class="dl">'</span><span class="p">);</span> <span class="c1">// 既存の S3 バケットを利用したい場合はこちら</span> <span class="c1">// const arn = 'arn:aws:s3:::...';</span> <span class="c1">// const sourceBucket = Bucket.fromBucketArn(this, 'ExistsBucket', arn);</span> <span class="c1">// ACM の承認は手動になるため、メールチェックして approve しないとデプロイ進行しない</span> <span class="kd">const</span> <span class="nx">certificate</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">certificatemanager</span><span class="p">.</span><span class="nx">Certificate</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Certificate</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span> <span class="na">domainName</span><span class="p">:</span> <span class="dl">'</span><span class="s1">cdk.sunaba.sh</span><span class="dl">'</span><span class="p">,</span> <span class="na">subjectAlternativeNames</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">cdk.sunaba.sh</span><span class="dl">'</span><span class="p">],</span> <span class="p">});</span> <span class="c1">// 既存の ACM を利用したい場合はこちら</span> <span class="c1">// const arn = 'arn:aws:...';</span> <span class="c1">// const certificate = Certificate.fromCertificateArn(this, 'Certificate', arn);</span> <span class="kd">const</span> <span class="nx">distribution</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">cloudfront</span><span class="p">.</span><span class="nx">CloudFrontWebDistribution</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="dl">'</span><span class="s1">ZaruCDKDistribution</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span> <span class="na">originConfigs</span><span class="p">:</span> <span class="p">[</span> <span class="p">{</span> <span class="na">s3OriginSource</span><span class="p">:</span> <span class="p">{</span> <span class="na">s3BucketSource</span><span class="p">:</span> <span class="nx">sourceBucket</span><span class="p">,</span> <span class="p">},</span> <span class="na">behaviors</span><span class="p">:</span> <span class="p">[{</span> <span class="na">isDefaultBehavior</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="na">lambdaFunctionAssociations</span><span class="p">:</span> <span class="p">[</span> <span class="p">{</span> <span class="na">eventType</span><span class="p">:</span> <span class="nx">cloudfront</span><span class="p">.</span><span class="nx">LambdaEdgeEventType</span><span class="p">.</span><span class="nx">ORIGIN_REQUEST</span><span class="p">,</span> <span class="na">lambdaFunction</span><span class="p">:</span> <span class="nx">fnVersion</span><span class="p">,</span> <span class="p">},</span> <span class="p">],</span> <span class="p">}],</span> <span class="p">},</span> <span class="p">],</span> <span class="na">viewerCertificate</span><span class="p">:</span> <span class="nx">cloudfront</span><span class="p">.</span><span class="nx">ViewerCertificate</span><span class="p">.</span><span class="nx">fromAcmCertificate</span><span class="p">(</span> <span class="nx">certificate</span><span class="p">,</span> <span class="p">{</span> <span class="na">aliases</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">cdk.example.com</span><span class="dl">'</span><span class="p">],</span> <span class="na">securityPolicy</span><span class="p">:</span> <span class="nx">cloudfront</span><span class="p">.</span><span class="nx">SecurityPolicyProtocol</span><span class="p">.</span><span class="nx">TLS_V1</span><span class="p">,</span> <span class="na">sslMethod</span><span class="p">:</span> <span class="nx">cloudfront</span><span class="p">.</span><span class="nx">SSLMethod</span><span class="p">.</span><span class="nx">SNI</span><span class="p">,</span> <span class="p">},</span> <span class="p">),</span> <span class="p">});</span> <span class="p">}</span> <span class="p">}</span> </pre> <p>こんな感じで AWS CDK で Lambda を管理するサンプルコード集でした。また運用していく中で使えるものがあれば反映していきます。</p></div></div><div class="article-sns-share-buttons"><a rel="nofollow" target="_blank" class="pocket-share sns-share-button" href="http://getpocket.com/edit?title=AWS+CDK+%E3%81%A7+TypeScript+Lambda+%E3%82%92%E3%81%84%E3%81%84%E6%84%9F%E3%81%98%E3%81%AB%E7%AE%A1%E7%90%86%E3%81%99%E3%82%8B%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89%E9%9B%86+by+zaru+%7C+Basicinc+Enjoy+Hacking%21&url=https%3A%2F%2Ftech.basicinc.jp%2Farticles%2F213"><svg class="sns-icon pocket-icon"><use xlink:href="/assets/icons-5bbe775037b55281ef0bc50d30a51f69c7c3914d399c7107e37f0702d98ae8a2.svg#pocket"></use></svg></a><a rel="nofollow" target="_blank" class="hatena-share sns-share-button" href="http://b.hatena.ne.jp/add?mode=confirm&title=AWS+CDK+%E3%81%A7+TypeScript+Lambda+%E3%82%92%E3%81%84%E3%81%84%E6%84%9F%E3%81%98%E3%81%AB%E7%AE%A1%E7%90%86%E3%81%99%E3%82%8B%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89%E9%9B%86+by+zaru+%7C+Basicinc+Enjoy+Hacking%21&url=https%3A%2F%2Ftech.basicinc.jp%2Farticles%2F213"><svg class="sns-icon hatena-icon"><use xlink:href="/assets/icons-5bbe775037b55281ef0bc50d30a51f69c7c3914d399c7107e37f0702d98ae8a2.svg#hatena"></use></svg></a><a rel="nofollow" target="_blank" class="twitter-share sns-share-button" href="https://twitter.com/share?text=AWS+CDK+%E3%81%A7+TypeScript+Lambda+%E3%82%92%E3%81%84%E3%81%84%E6%84%9F%E3%81%98%E3%81%AB%E7%AE%A1%E7%90%86%E3%81%99%E3%82%8B%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89%E9%9B%86+by+zaru+%7C+Basicinc+Enjoy+Hacking%21&url=https%3A%2F%2Ftech.basicinc.jp%2Farticles%2F213"><svg class="sns-icon twitter-icon"><use xlink:href="/assets/icons-5bbe775037b55281ef0bc50d30a51f69c7c3914d399c7107e37f0702d98ae8a2.svg#twitter"></use></svg></a><a rel="nofollow" target="_blank" class="facebook-share sns-share-button" href="http://www.facebook.com/share.php?u=https%3A%2F%2Ftech.basicinc.jp%2Farticles%2F213"><svg class="sns-icon facebook-icon"><use xlink:href="/assets/icons-5bbe775037b55281ef0bc50d30a51f69c7c3914d399c7107e37f0702d98ae8a2.svg#facebook"></use></svg></a></div></article></div><footer data-scope-path="layouts/_footer"><div class="footer-contents"><a class="root-link" href="/"><svg class="site-logo"><use xlink:href="/assets/icons-5bbe775037b55281ef0bc50d30a51f69c7c3914d399c7107e37f0702d98ae8a2.svg#logo"></use></svg><div class="site-title">Enjoy Hacking!</div></a><ul class="link-list"><li class="link-list-item"><a class="link" href="https://basicinc.jp/" rel="noopener" target="_blank">株式会社ベーシック</a></li><li class="link-list-item"><a class="link" href="https://basicinc.jp/enjoy-hacking" rel="noopener" target="_blank">エンジニア募集</a></li><li class="link-list-item"><a class="link" href="https://qiita.com/organizations/basicinc" rel="noopener" target="_blank">Qiita</a></li><li class="link-list-item"><a class="link" href="https://www.wantedly.com/companies/basicinc/projects" rel="noopener" target="_blank">Wantedly</a></li></ul></div></footer></body></html>