CloudFormationのスタック(Stack)を更新しても、更新されないリソース

まえおき

 CloudFormationを使っているとスタック(Stack)の更新をすることがある。今までCloudFormation内をリソースを更新したときに、更新されなくて戸惑った3つの場合について書いてみる。

 

1. LambdaのコードをS3に保存した場合

 当たり前かもしれないけど、その更新は最新のCloudFormationのテンプレートと旧テンプレートの差分より更新される。つまり、「テンプレートに変更がないとスタック内のリソースに更新は発生しない」ということだ。AWS::Lambda::FunctionCode属性の記載方法には2つがある。テンプレート内に直接記載する方法とS3にファイルをアップロードし、そのバケット名とパスを記載する方法だ(関連ドキュメント)。ここで更新時に問題になるのはS3にLambdaファイルを更新する場合だ。S3のファイルを更新しても、CloudFormationテンプレート内のコードは変わることなく、S3ファイルの変化の検知もしないので、Lambdaが更新されない。私は以下の2つの方法で更新した。

 

方法1 S3パスを更新する

 シンプルな方法である。AWS::Lambda::FunctionCode属性を変更すれば、テンプレートに変更点が発生するのでLambdaを更新するkとおができる。私は日付ごとにフォルダを作成、更新するLambdaをおきテンプレートを修正するようにしていた。しかし、当時はCI/CD環境ではなかったので、テストでLambdaに修正点があれば、都度S3にファイルをアップロードして日付を修正&デプロイまたはテンプレートをロールバック&デプロイする必要があった。ミスも多く発生していた。そこで、CI/CD環境を整えることと同時に方法2の方法を利用することにした。

 

方法2 SAMを利用する(おすすめ)

 SAM(Serverless Application Package) を利用する方法だ。SAMテンプレートを書いて、コマンドを実行すると以下が実行される。

  • Lambdaファイルはランダム文字列のファイル名でS3にアップロードされる
  • テンプレートをCloudFormationテンプレートに変換して、S3にアップロードしたLambdaのパスが記載してくれる。

 ちなみに、SAMテンプレートにはCloudFormationの内容も記載できるので、SAMを利用したいところだけSAM文法で書けばよい。変換コマンドAWS CLIのaws cloudformation pacakgeとSAMのsam pacakgeを利用する。sam packageコマンドは、aws cloudformation package のエイリアスなので、違いはない。ただ、下のStepfunctionに出るが最新のアップデートはsam packageの方でアップデートされ、まだaws cloudformation packageではできない場合もあるので、sam packageを利用した方がいいかもしれない。この方法の短所は変換過程が必要なことと、1つのLambdaを直しても変換をするときにテンプレート内のすべての(SAMで記述された)lambda関数に対してアップロードをされるので、微々たるものだけどS3容量の無駄(?)が発生すること。でも、アップロードする手間を防げる点では方法1よりはこっちの方法をおすすめする。ついでに、CodePipelineでCodeCommit(またはGithub)→CodeBuild(ここで変換)→Cloudformationのパイプラインを組んでおくと楽に変換とデプロイができる。

参考ページ

 

2. StepFunctionsをS3に保存した場合

 上記のLambdaと同じようにStepFunctionsのテンプレートコードをAWS::StepFunctions::StateMachineDefinitionS3Location属性を利用してS3上ファイルに保存した場合にDefinitionS3Location内の内容が変更されないと変更がないこととなり、StateMachineが更新されない。詳細は前回書いたCloudFormationテンプレート内のStep functionsのState machine定義をS3に置けるようになったを参照。更新方法としてもLambdaと同じように、S3パスを更新するか、SAMを利用すればよい。SAMを利用する場合は、DefinitionS3Locationは割と最新アップデートなので、SAMやCLIのバージョンが古いとうまく変換&アップロードしてくれないことに注意する必要がある。(私が何か月前に触ったときはSAM packageはできたが、Cloudformation pacakgeではエラーとなった)

 

3. REST API Gatewayを更新してもデプロイされない

 REST API形式のAPI Gatewayを利用している場合は、設定を更新するとデプロイを行う必要がある。問題はCloudformationでAPI Gatewayを更新する場合、設定の更新はされるがデプロイまではしてくれないことだ。ネットを探しても、手動でデプロイするか、カスタムリソースを使ってデプロイをする方法しかないみたい。

 またはsam deployを利用してデプロイまで行えばできそうな気もするが、SAM CLIでアプリケーションを管理しないといけなさそうだったので、まだ試してはいない。ちなみに業務では手動でデプロイする方法を利用している。リリースルール上、決められたリリース日に本番環境に入ってリリースをしないといけないので、パイプラインで配布が終わった後にAPIGatewayのデプロイをする流れでやっている。

 ちなみに、このことについて記事?ネット情報があまりなかったけど、みんな当たり前なことだと思っているのかな?私はデプロイされないことを知って結構驚いたけど…。

 

まとめ

 Cloudformationでスタックを更新しても更新されない場合について書いてみた。ここら辺のことは、学習時はわからない場合が多く、実際に業務を行ってからわかるようになることが多いように思われる。今後、追加で更新されないことがあれば追記するようにしたい。

Popular Posts

CloudWatch EventsはAmazon EventBridgeになるらしい

PythonのDict型をDynamoDB形式のJsonに変換する

CloudFormationテンプレート内のStep functionsのState machine定義をS3に置けるようになった