はじめに
この記事は、TypeScript Advent Calendar 2019 #13日目 の記事です。
13日目担当の @is_ryo です!
謝辞
あまりTypeScriptの話ではありません…申し訳ございません……
はじめに(2回目)
私のいるチームではAWSの構成管理をするためにAWSCDKを使っています。
AWSCDKとは、CloudFormation(以下CFn)のテンプレートをTypeScriptやPythonといった言語で生成することができる開発キットです。
ここではAWSCDK自体の説明は省きます。詳しくは公式ページを参考にして下さい。
何が起こったか…
LambdaLayer を試験的に導入していこうとなり、普段通りにCDKをTypeScriptで書いていました。
ソースコードはこんな感じ
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
メンバー「コンソールで確認してみるか」
コンソール「デプロイできてるで」
メンバー「ちょっとLambdaLayerのロジック変えたからデプロイしなおすか」
〜〜省略〜〜
コンソール「デプロイできてるで」
メンバー「おい…バージョン1どこにやった?」
コンソール「勘のいいガ(ry」
原因は何?
CFnが犯人。というかCFnの性質かと思われる。
スタックに定義していないリソースに関してはわざわざDeleteされる場合があります。
例えばAPIGatewayに /get
と /post
というresourceがあったときに、そのAPIGatewayに /get
だけのスタックでUpdateをすると /post
がDeleteされます。
これと同じように、スタックをUpdateしたときには前のバージョンの情報は持ってないのでDeleteされていました…
対処方法
勝手に消されないようにしましょう。
CFnで生成するリソースに対して removal policy
というプロパティを設定することができます。
そのプロパティを Retain
にすることで削除保護されます。
書き方はこんな感じ
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)
試す
メンバー「デプロイや!」
コンソール「デプロイできてるで」
メンバー「前のバージョンも残ってる!」
さいごに
いかがでしょうか。
CFnを書いてる方からすると当たり前じゃんって感じなのかもしれませんが、CFnに消されて困るものがあるときは removal policy
をちゃんと付けてあげましょう。
ただ注意点として一度 removal policy
を RETAIN
でデプロイするとCFnでは削除できなくなります。コンソールから消したりする必要があります。
ではまた!