LoginSignup
7
2

More than 3 years have passed since last update.

AWSCDK for TypeScript で LambdaLayer をデプロイすると前のバージョンが消し飛ぶんだが………

Last updated at Posted at 2019-12-13

はじめに

この記事は、TypeScript Advent Calendar 2019 #13日目 の記事です。
13日目担当の @is_ryo です!

謝辞

あまりTypeScriptの話ではありません…申し訳ございません……

はじめに(2回目)

私のいるチームではAWSの構成管理をするためにAWSCDKを使っています。
AWSCDKとは、CloudFormation(以下CFn)のテンプレートをTypeScriptやPythonといった言語で生成することができる開発キットです。
ここではAWSCDK自体の説明は省きます。詳しくは公式ページを参考にして下さい。

何が起こったか…

LambdaLayer を試験的に導入していこうとなり、普段通りにCDKをTypeScriptで書いていました。
ソースコードはこんな感じ

stack.ts
import cdk = require("@aws-cdk/core")

import { LayerVersion, AssetCode, Runtime } from "@aws-cdk/aws-lambda"

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

    new LayerVersion(this, "DemoLambdaLayer", {
      code: AssetCode.fromAsset("lambdaSources/demo_function"),
      compatibleRuntimes: [Runtime.NODEJS_12_X]
    })
  }
}

メンバー「よし、ソース書けたからデプロイするで!」

$ aws cdk deploy LambdaLayerStack

メンバー「コンソールで確認してみるか」

コンソール「デプロイできてるで」

lambda_layer_1.png

メンバー「ちょっとLambdaLayerのロジック変えたからデプロイしなおすか」

〜〜省略〜〜

コンソール「デプロイできてるで」

lambda_layer_2.png

メンバー「おい…バージョン1どこにやった?」

コンソール「勘のいいガ(ry」

原因は何?

CFnが犯人。というかCFnの性質かと思われる。
スタックに定義していないリソースに関してはわざわざDeleteされる場合があります。
例えばAPIGatewayに /get/post というresourceがあったときに、そのAPIGatewayに /get だけのスタックでUpdateをすると /post がDeleteされます。
これと同じように、スタックをUpdateしたときには前のバージョンの情報は持ってないのでDeleteされていました…

対処方法

勝手に消されないようにしましょう。
CFnで生成するリソースに対して removal policy というプロパティを設定することができます。
そのプロパティを Retain にすることで削除保護されます。
書き方はこんな感じ

stack.ts
import cdk = require("@aws-cdk/core")

import { LayerVersion, AssetCode, Runtime } from "@aws-cdk/aws-lambda"

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

    const lambdaLayer = new LayerVersion(this, "DemoLambdaLayer", {
      code: AssetCode.fromAsset("lambdaSources/demo_function"),
      compatibleRuntimes: [Runtime.NODEJS_12_X]
    })
    /* ここから追加 */
    const lambdaLayerResource = lambdaLayer.node.findChild(
      "Resource"
    ) as cdk.CfnResource
    lambdaLayerResource.applyRemovalPolicy(cdk.RemovalPolicy.RETAIN)
  }
}

軽く説明する

applyRemovalPolicy という関数を使うためには cdk.CfnResource を変数に入れる必要があります。

const lambdaLayerResource = lambdaLayer.node.findChild(
  "Resource"
) as cdk.CfnResource

applyRemovalPolicy という関数を使って removal policy を設定します。
基本的にデフォルトは DELETE になっています。

lambdaLayerResource.applyRemovalPolicy(cdk.RemovalPolicy.RETAIN)

試す

メンバー「デプロイや!」

コンソール「デプロイできてるで」

lambda_layer_3.png

メンバー「前のバージョンも残ってる!」

さいごに

いかがでしょうか。
CFnを書いてる方からすると当たり前じゃんって感じなのかもしれませんが、CFnに消されて困るものがあるときは removal policy をちゃんと付けてあげましょう。
ただ注意点として一度 removal policyRETAIN でデプロイするとCFnでは削除できなくなります。コンソールから消したりする必要があります。
ではまた!

7
2
1

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
7
2