0
0

SAMを使用せずCodePipeline内でLambdaコードの更新を反映させる手段

Last updated at Posted at 2024-07-16

CloudFormationでIaCを構成しているとき、テンプレートの更新は反映されても、Lambdaのコードの更新が反映されない場合があります。
SAMを使用せず、以下のようなLambdaのテンプレートでデプロイしようとした時に発生しました。

lambda.yaml
  TestPythonCode: 
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: TestPythonCode
      Code: 
        S3Bucket: !Ref RootBucket
        S3Key: 'TestPythonCode.zip'
      Role: 'arn:aws:iam::${AWS::AccountId}:role/lambdaExecusionRole'
      Handler: fileName.lambda_handler'
      Runtime: python3.12

この場合、S3Keyの値に更新がないと、CloudFormationの更新でLambdaのデプロイが反映されません。
変更セットに値の変更がないため、デプロイが実行されないようです。

解決策

CodeBuild内でTimeStampを生成して、LambdaのZipファイル名につける。

S3のZip名にタイムスタンプを組み込むことで、CloudFormation内で毎回Lambda.zipファイルのデプロイが行われるようになります。

記載例

タイムスタンプ作成シェル

timestamp.sh
#!/bin/bash

# 変数に格納
timestamp=$(date +"%Y%m%d%H%M%S")
echo $timestamp

LambdaをZip化するCodeBuildのアクション

BuildSpec.yaml
          version: 0.2
          # ここでのちのアクションに受け渡す環境変数を作成
          env:
            exported-variables:
              - TIMESTAMP_LAMBDA
          phases:
            install:
              runtime-versions:
                python: 3.11
              command:
                - echo install
                - pip install --upgrade pip
                - pip install --upgrade --user awscli
                - aws --version
            pre_build:
              commands:
                - echo pre_build
            build:
              commands:
                - echo "CloudFormation Build"
            post_build:
              commands:
                - echo "CloudFormation template S3 push"
                - pwd
                - cd ./deploy/template/lambda/src
                - export TIMESTAMP_LAMBDA=$(sh ./timestamp.sh) # 環境変数にタイムスタンプを指定
                - echo $TIMESTAMP_LAMBDA
                - sh ./build.sh "$TIMESTAMP_LAMBDA"
                - cd ../../../../../
                - pwd
                - aws s3 cp ./02_deploy/$EnvironmentType s3://deploy/ --recursive --exclude "*" --include "*.yaml" --include "*.zip"

CodePipelineのテンプレート

codepipeline.yaml
Resources:
  # Deploy Pipeline
  ppline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      # ~パイプラインの設定省略~ 
      
      Stages:
      # 変更セット作成ステージ
      - Name: ChangeSetCreateStage
        Actions:
          - Name: ChangeSetReplaceAction
            ActionTypeId:
              Category: Deploy
              Owner: AWS
              Version: 1
              Provider: CloudFormation
            InputArtifacts:
              - Name: SourceZip
            Configuration:
              ChangeSetName: Hoge
              ActionMode: CHANGE_SET_REPLACE
              StackName: Hoge
              Capabilities: CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND
              TemplatePath: "TemplateFilePath"
              RoleArn: "RoleArn"
            RunOrder: 1
            
    # 変更セットデプロイステージ
      - Name: Deploy
        Actions:
          - Name: DeployRoot1
            ActionTypeId:
              Category: Deploy
              Owner: AWS
              Provider: CloudFormation
              Version: 1
            Configuration:
              ActionMode: CHANGE_SET_EXECUTE
              RoleArn: "RoleArn"
              StackName: Hoge
              ChangeSetName: Hoge
              # CodeBuild内で作成したタイムスタンプを指定
              ParameterOverrides: !Sub |
                {
                  "TimeStampLambda": "#{BuildVariables.TIMESTAMP_LAMBDA}"
                }

ParameterOberridesの項で、BuildSpec.yaml内でエクスポートした環境変数を指定してCloudFormationのパラメータに指定しています。

Lambdaのテンプレート

Lambda.yaml
  TestPythonCode: 
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: TestPythonCode
      Code: 
        S3Bucket: "TestBucketS3URI"
        # ポストフィックスにタイムスタンプをつける
        S3Key: 'TestPythonCode_${TimeStampLambda}.zip'
      Role: 'arn:aws:iam::${AWS::AccountId}:role/lambdaExecusionRole'
      Handler: fileName.lambda_handler'
      Runtime: python3.12

S3のZip名にタイムスタンプを組み込むことで、CloudFormation内で毎回Lambda.zipファイルのデプロイが行われるようになります。

最後に

今回は既存のソースコードを修正、かつSAMを使わないという縛りだったため、このようになりましたが、
新規開発の場合はSAMを使用してcloudformation --packageをした方が良いかと思います。

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