0
0

CloudFormationでlambdaのソースコードを更新する方法

Posted at

背景

CloudFormation(以降、cfnと記載)を使用して、lambdaソースコードの更新を行いたい時があると思います。
cfnでは、テンプレートファイルに変更があれば更新してくれますが、lambdaのソースコードをS3にアップロードしている場合、lambdaのS3BuketやS3Keyは変化しないので、テンプレートファイルには変更が起きず、結果的にcfnでの更新ができません。

Resources:
  layer:
    Type: AWS::Lambda::LayerVersion
    Properties:
      Description: 'pacakge deploy test layer'
      LayerName: 'PacakgeDeployTestLambdaLayer'
      Content:
            S3Bucket: Hoge
            S3Key: Layer.zip // Layerの内容を更新してもここの値は一定

  Lambda:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: 'PacakgeDeployTestLambda'
      Description: 'pacakge deploy test lambda'
      Handler: handler.index
      Role: !Ref LambdaIamRoleArn
      Runtime: python3.10
      MemorySize: 128
      PackageType: Zip
      Architectures: 
        - x86_64
      Layers: 
        - !Ref layer
      Code:
          S3Bucket: Hoge
          S3Key: Source.zip // Sourceの内容を更新してもここの値は一定

今回はその対応策をまとめたいと思います。

結論

aws cloudformation packageを使用しよう

aws cloudformation packageコマンドとは?

cfnのテンプレートファイルで記載したファイルやディレクトリを自動でS3にアップロードしてくれて、アップロードしたS3URIをテンプレートファイルに自動で記載してくれるコマンドです。
以下のサイトが参考になるかもです。

具体例

例えば、以下のようなフォルダ構成を考えます。
LambdaのソースコードディレクトリやLayerディレクトリのS3BucketやS3Keyがcfnのテンプレートファイルに自動で更新されたら目的達成です。
image.png
目標を達成するために以下の手順を実行します

  1. cfnテンプレートファイルの修正
  2. aws cloudformation packageの実行
  3. 生成されたテンプレートファイルの確認
  4. 手順2で自動生成されたテンプレートファイルを使用してDeploy

1. cfnテンプレートファイルの修正

S3の値を指定いた部分を修正します

Resources:
  layer:
    Type: AWS::Lambda::LayerVersion
    Properties:
      Description: 'pacakge deploy test layer'
      LayerName: 'PacakgeDeployTestLambdaLayer'
      Content: ./layer // templeteファイルから見た相対パス

  Lambda:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: 'PacakgeDeployTestLambda'
      Description: 'pacakge deploy test lambda'
      Handler: handler.index
      Role: !Ref LambdaIamRoleArn
      Runtime: python3.10
      MemorySize: 128
      PackageType: Zip
      Architectures: 
        - x86_64
      Layers: 
        - !Ref layer
      Code: ./source // templeteファイルから見た相対パス

2. aws cloudformation packageの実行

今回はCloudShellを使用してコマンドをたたきます
そのため、テンプレートファイルやSourceディレクトリなどを1つのフォルダにまとめてZip化し、CloudShellにアップロードします。(この際、SourceディレクトリやLayerディレクトリを先にZip化する必要はありません)
CloudShellのアクションから「アップロード」を選択し、Zip化したファイル一式をアップロードします
image.png
Unzipしてディレクトリに移動します
image.png
ここで aws cloudformation packageコマンドをたたきます

aws cloudformation package --template-file 'package.yaml' --s3-bucket 'cfn-test-main' --s3-prefix lambda --region 'XXXXX-1' --output-template-file 'Lambda.yaml'

各引数の意味

--template-file → S3の値を書き換えたいcfnのテンプレートファイルのパス
--s3-bucket → SourceやLayerなどをアップロードするS3バケット名
--s3-prefix → S3にアップロードしたいディレクトリ.指定がなければ、S3バケット直下にアップロードされる
--region → バケットのリージョン?なくてもいい
--output-template-file → S3の値を書き換えたテンプレートファイルの名前.指定がなければ標準出力に出される

すると、Lambda.yamlというファイルが生成されています。
image.png
内容を確認するために、CloudShellのアクションから「ファイルダウンロード」を選択します。
ファイルパスは以下だと思います。※Pacakgeとかは各自で異なります

/home/cloudshell-user/Package/lambda.yaml

3. 生成されたテンプレートファイルの確認

以下の内容のように、ContentやCodeの部分の値が変更されています。

Resources:
  layer:
    Type: AWS::Lambda::LayerVersion
    Properties:
      Description: pacakge deploy test layer
      LayerName: PacakgeDeployTestLambdaLayer
      Content:
        S3Bucket: cfn-test-main // --s3-bucketで指定した値
        S3Key: lambda/f36168fedef3585c635ae45f998a6706 // 自動で割り当てられる乱数
  Lambda:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: PacakgeDeployTestLambda
      Description: pacakge deploy test lambda
      Handler: handler.index
      Role:
        Ref: LambdaIamRoleArn
      Runtime: python3.10
      MemorySize: 128
      PackageType: Zip
      Architectures:
      - x86_64
      Layers:
      - Ref: layer
      Code:
        S3Bucket: cfn-test-main // --s3-bucketで指定した値
        S3Key: lambda/391f85c3f6f07f7a979cbc243fea3f83 // 自動で割り当てられる乱数

S3バケットを確認すると指定したバケットのlambdaフォルダ内に自動で割り当てられた乱数のファイルが存在していることが分かります
image.png
ここまでで、コマンドを使用したテンプレートファイルの生成とS3へのアップロードが確認できました。
テンプレートファイルには、lambdaのソースコード置き場の値が変更されているので、cfnを使用してlambdaが自動で更新されることができると思います。

4. 手順2で自動生成されたテンプレートファイルを使用してDeploy

コマンドで生成されたテンプレートファイルでlmabdaを更新してみます。
今回はテンプレートファイルをS3に置いて、AWSマネジメントコンソールでcloudformationサービスをポチポチしながらdeployしてみたい思います。
aws cloudformation packageコマンドで作成されたテンプレートファイルをS3に配置します
AWSマネジメントコンソールでcloudformationからstackを立ち上げます
image.png
自動でアップロードされたsoruceコードがアップロードされていることが確認できます
image.png

まとめ

今回はaws cloudformation packageコマンドを使用して、cloudformationでLambda, Lambda Layerを更新する方法を紹介しました。
今回はAWSマネジメントコンソールで更新処理をしましたが、aws cloudformation deployコマンドを使用すれば手作業をより減らして対応できるかもですね。

0
0
0

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