こんにちは、広野です。
いわゆるコードだけ書いたらすぐ動く AWS Lambda 関数はいじったことのある方は多いと思いますが、コンテナイメージを AWS Lambda 関数として使ったことがある方は比較的少ないのではないでしょうか。(以降、コンテナ Lambda と表記)
業務でやや重めの処理をするワークロードがありコンテナ Lambda をつくったのですが、手動でのビルドが面倒になってきたので CI/CD 環境までつくってみました。ネット上で紹介されている環境よりも若干簡易な構成になっています。
最終章に AWS CloudFormation テンプレートを貼り付けますので、AWS アカウントをお持ちの方はお気軽にお試しください。CI/CD の学習用にも良いサンプルになると思います。
アーキテクチャ
最初にどんな設計なのか説明します。
図の左上から。
- 開発者は、AWS Cloud9 上で AWS Lambda 関数を開発します。本記事では Python 3.9 を使用します。図では省略していますが、ここで Dockerfile、buildspec.yml、requirements.txt、それと Lambda 関数をデプロイするための AWS CloudFormation テンプレートもソースコードと一緒に配置・管理します。
- AWS Cloud9 で開発したコードやその他ファイルを、AWS CodeCommit にプッシュします。それを Amazon EventBridge が検知して、AWS CodePipeline を開始します。
- AWS CodePipeline は、最初にソースコードを AWS CodeCommit に取りにいきます。ここでは、ソースコードがどこにあるか情報だけを JSON データにして取得するだけで、それをアーティファクト保存用 Amazon S3 バケットに保存します。
- 次に AWS CodePipeline は AWS CodeBuild を呼び出します。あらかじめ設定済みのビルドプロジェクトを開始し、ビルドプロジェクトはアーティファクト保存用バケットに保存されたソースコード情報 JSON ファイルを読み込み、AWS CodeCommit にソースコードを取得しに行きます。
- その後 AWS CodeBuild はソースコードおよび一緒に保存してあるその他ファイルを読み込み、その記述に従ってコンテナイメージをビルドします。コンテナイメージは Amazon ECR (Elastic Container Registry) に保存します。このとき、コンテナイメージを一意に識別するために AWS CodePipeline のパイプライン実行単位で割り当てられる「パイプライン実行 ID」をコンテナイメージの「イメージタグ」として付与します。後ほど必要になります。
- AWS CodeBuild は最後に、ソースコードと同梱されていた AWS CloudFormation テンプレートをそのまま加工せずにアーティファクト保存用 Amazon S3 バケットに保存します。そうしないと、次のデプロイフェーズでスタック作成ができないためです。※このビルドフェーズで、SAM を使って AWS CloudFormation テンプレートを作成、保存する方法もあります。
- デプロイフェーズでは、いよいよコンテナ Lambda 関数をデプロイします。アーティファクト保存用 Amazon S3 バケットから AWS CloudFormation テンプレートを受け取り、スタック作成を実行します。ここで、再度 AWS CodePipeline の「パイプライン実行 ID」を AWS CloudFormation にパラメータとして渡します。ビルドフェーズで使用したものと同じ情報になります。
- AWS CloudFormation は「パイプライン実行 ID」をイメージタグに持つコンテナイメージをコンテナ Lambda 関数の関連付け対象に指名します。それにより、そのパイプライン実行で作成された最新のコンテナイメージを一意に指定して、コンテナ Lambda 関数をデプロイし直す(スタックの変更)ことができます。
- Amazon ECR に保存されるコンテナイメージは直近 5 世代まで保存するようにしています。無尽蔵にイメージがたまって課金を増やすことのないようにしていますが、保管のポリシーによってこのライフサイクルポリシーは変更した方がよいでしょう。
使用方法
CI/CD 環境・開発環境準備
本記事最下部「サンプルテンプレート」に掲載している AWS CloudFormation テンプレートを実行して CI/CD 環境をプロビジョニングします。
その前提で、以下 AWS 公式ドキュメントを参考に AWS Cloud9 環境を構築します。クローンする AWS CodeCommit のリポジトリ名は example-lmbd-xxxxx になっています。xxxxx はスタック作成時に任意に入力するパラメータです。リソース名に必ず入る文字列になります。
プロビジョニング完了直後、パイプラインが自動実行されてしまい、そして必ず失敗しますので失敗ステータスは気にしないで下さい。
開発環境への AWS Lambda 関数コード等アップロード
本記事最下部「サンプルテンプレート」に掲載している以下 5 つのファイルを AWS Cloud9 に作成またはアップロードします。ディレクトリは、AWS CodeCommit のリポジトリをクローンしたときに出来たディレクトリになります。
- app.py
- Dockerfile
- requirements.txt
- buildspec.yml
- Cfn_LambdaContainer.yml
本記事で使用する AWS Lambda 関数のコードは、簡便化のため AWS 公式ドキュメントで紹介されているものを使用します。以下のリンクを参考に、app.py を作成してみて下さい。
Dockerfile も上記ページで紹介されている通りに作ればよいのですが、Python のバージョンは 3.9 にしたいので 3.8 を 3.9 に書き換えましょう。
requirements.txt は、pip を使用して必要な外部モジュールをインストールする際に使用します。(使用しなくてもいいのですが)
本記事のケースでは外部モジュールは必要ないのですが、学習のために以下のように書いてみましょう。書くことにより、ビルド時にこれらをインストールしてコンテナイメージに含めてくれます。ここでインストールしたモジュールは、関数コード内で import できるようになります。
requirements.txt
numpy==1.24.2 opencv-python==4.7.0.72
buildspec.yml はビルド内のフェーズごとに何をさせるか指定するためのファイルです。以下の AWS 公式ドキュメントのサンプルは汎用的にするために環境変数をしっかり設定してくれているので、これに合わせてビルドプロジェクトを作成すれば綺麗な CI/CD をつくれます。
ただし、本記事の構成では、AWS コンテナ Lambda 関数をデプロイするための AWS CloudFormation テンプレートをソースコードとともにビルド環境に持ってきており、次のデプロイフェーズにビルドアーティファクトとしてテンプレートを渡す必要があります。そのため buildspec.yml に上記サンプルに加えて artifacts: の設定を追加します。具体的には以下の記述になります。
buildspec.yml
version: 0.2 phases: pre_build: commands: - echo Logging in to Amazon ECR... - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com build: commands: - echo Building the Docker image... - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG . - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG post_build: commands: - echo Pushing the Docker image... - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG artifacts: files: - Cfn_LambdaContainer.yml
Cfn_LambdaContainer.yml は AWS コンテナ Lambda 関数を作成または更新するための AWS CloudFormation テンプレートです。パイプラインのデプロイフェーズで同じテンプレートが実行されることになりますが、パラメータとして渡されるパイプライン実行 ID が毎回変わるため、2 回目の実行以降は必ず変更扱いになります。このファイルについては最下部の「サンプルテンプレート」の章をご確認ください。
最終的に、5 つのファイルを AWS Cloud9 に配置すると以下のようになります。
CI/CD パイプラインの発動
以降は、これらコードや設定ファイルを更新する度に AWS CodeCommit にプッシュすると CI/CD パイプラインが自動発動し AWS コンテナ Lambda 関数が自動的にビルド・デプロイされます。
- AWS Cloud9 からの最も簡単なプッシュコマンド例
cd example-lmbd-xxxxx git add -A git commit -m "comment" git push origin master
以下のように AWS CodePipeline の画面でパイプラインが実行されていることが確認できます。デプロイフェーズがグリーンで「成功しました」になれば完了です。
AWS コンテナ Lambda 関数のテスト実行
本記事の構成でデプロイされる AWS コンテナ Lamda 関数の名前は EXAMPLE-getPythonVersion-xxxxx になります。2 回目以降のデプロイでは関数の名前は変わらず、関連付けられているコンテナイメージが変わります。
対象の AWS コンテナ Lambda 関数のテストを実行すると、app.py に書いたコードが実行され、以下のような Python のバージョンが戻り値として表示されます。
AWS Lambda 関数のテストをする方法は以下の AWS ドキュメントをご覧下さい。本記事のケースでは、テストイベントはデフォルトのままでかまいません。パラメータ渡しをしていないため。
まとめ
いかがでしたでしょうか?
コンテナ Lambda の基本的な CI/CD はできていると思いますので、細かいパラメータをカスタマイズするだけでご活用頂けると思います。
本記事が皆様のお役に立てれば幸いです。
サンプルテンプレート
AWS CloudFormation テンプレート (CI/CD 環境作成用)
AWSTemplateFormatVersion: 2010-09-09 Description: The CloudFormation template that creates a CICD environment for a container Lambda function. # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: SubName: Type: String Description: System sub name of EXAMPLE. (e.g. prod, test or your name) Default: yourname MaxLength: 10 MinLength: 1 Resources: # ------------------------------------------------------------# # S3 # ------------------------------------------------------------# S3BucketArtifact: Type: AWS::S3::Bucket Properties: BucketName: !Sub example-${SubName}-artifact PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true Tags: - Key: Cost Value: !Sub EXAMPLE-${SubName} S3BucketLogs: Type: AWS::S3::Bucket Properties: BucketName: !Sub example-${SubName}-logs PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true Tags: - Key: Cost Value: !Sub EXAMPLE-${SubName} # ------------------------------------------------------------# # ECR # ------------------------------------------------------------# EcrRepositoryLMBD: Type: AWS::ECR::Repository Properties: RepositoryName: !Sub example-get-python-version-${SubName} EncryptionConfiguration: EncryptionType: AES256 ImageScanningConfiguration: ScanOnPush: true ImageTagMutability: IMMUTABLE LifecyclePolicy: LifecyclePolicyText: | { "rules": [ { "rulePriority": 1, "description": "Keep only 5 images, expire all others", "selection": { "tagStatus": "any", "countType": "imageCountMoreThan", "countNumber": 5 }, "action": { "type": "expire" } } ] } Tags: - Key: Cost Value: !Sub EXAMPLE-${SubName} # ------------------------------------------------------------# # CodeCommit Repository # ------------------------------------------------------------# CodeCommitRepoLMBD: Type: AWS::CodeCommit::Repository Properties: RepositoryName: !Sub example-lmbd-${SubName} RepositoryDescription: !Sub Source Code for EXAMPLE-LMBD-${SubName} Tags: - Key: Cost Value: !Sub EXAMPLE-${SubName} # ------------------------------------------------------------# # CodePipeline # ------------------------------------------------------------# CodePipelineLMBD: Type: AWS::CodePipeline::Pipeline Properties: Name: !Sub EXAMPLE-${SubName}-LMBD ArtifactStore: Location: !Ref S3BucketArtifact Type: S3 RestartExecutionOnUpdate: false RoleArn: !GetAtt CodePipelineServiceRoleLMBD.Arn Stages: - Name: Source Actions: - Name: Source RunOrder: 1 ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: CodeCommit Configuration: RepositoryName: !GetAtt CodeCommitRepoLMBD.Name BranchName: master PollForSourceChanges: false OutputArtifactFormat: CODEBUILD_CLONE_REF Namespace: SourceVariables OutputArtifacts: - Name: Source - Name: Build Actions: - Name: Build RunOrder: 1 Region: !Sub ${AWS::Region} ActionTypeId: Category: Build Owner: AWS Version: 1 Provider: CodeBuild Configuration: ProjectName: !Ref CodeBuildProjectLMBD BatchEnabled: false EnvironmentVariables: | [ { "name": "IMAGE_TAG", "type": "PLAINTEXT", "value": "#{codepipeline.PipelineExecutionId}" } ] Namespace: BuildVariables InputArtifacts: - Name: Source OutputArtifacts: - Name: Build - Name: Deploy Actions: - ActionTypeId: Category: Deploy Owner: AWS Provider: CloudFormation Version: 1 Configuration: StackName: !Sub EXAMPLE-${SubName}-LambdaContainer Capabilities: CAPABILITY_NAMED_IAM RoleArn: !GetAtt CodePipelineDeployCreateUpdateRoleLMBD.Arn ActionMode: CREATE_UPDATE TemplatePath: Build::Cfn_LambdaContainer.yml ParameterOverrides: !Sub '{"SubName": "${SubName}","ImageTag":"#{codepipeline.PipelineExecutionId}"}' InputArtifacts: - Name: Build Name: CreateOrUpdate RoleArn: !GetAtt CodePipelineDeployCreateUpdateActionRoleLMBD.Arn RunOrder: 1 Tags: - Key: Cost Value: !Sub EXAMPLE-${SubName} DependsOn: - CodePipelineServiceRoleLMBD - CodeBuildProjectLMBD - CodePipelineDeployCreateUpdateActionRoleLMBD # ------------------------------------------------------------# # CodePipeline Service Role (IAM) # ------------------------------------------------------------# CodePipelineServiceRoleLMBD: Type: AWS::IAM::Role Properties: RoleName: !Sub EXAMPLE-CodePipelineServiceRoleLMBD-${SubName} Description: This role allows CodePipeline to call each stages. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - codepipeline.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: !Sub EXAMPLE-CodePipelineServiceRolePolicyLMBD-${SubName} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "codecommit:CancelUploadArchive" - "codecommit:GetBranch" - "codecommit:GetCommit" - "codecommit:GetRepository" - "codecommit:GetUploadArchiveStatus" - "codecommit:UploadArchive" Resource: !GetAtt CodeCommitRepoLMBD.Arn - Effect: Allow Action: - "codebuild:BatchGetBuilds" - "codebuild:StartBuild" - "codebuild:BatchGetBuildBatches" - "codebuild:StartBuildBatch" Resource: "*" - Effect: Allow Action: - "cloudwatch:*" - "s3:*" Resource: "*" - Effect: Allow Action: - "lambda:InvokeFunction" - "lambda:ListFunctions" Resource: "*" - Effect: Allow Action: "sts:AssumeRole" Resource: - !GetAtt CodePipelineDeployCreateUpdateActionRoleLMBD.Arn DependsOn: - CodeCommitRepoLMBD - CodePipelineDeployCreateUpdateActionRoleLMBD # ------------------------------------------------------------# # CodePipeline Deploy Create Update Role (IAM) # ------------------------------------------------------------# CodePipelineDeployCreateUpdateRoleLMBD: Type: AWS::IAM::Role Properties: RoleName: !Sub EXAMPLE-CdPlCreateUpdateRoleLMBD-${SubName} AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: cloudformation.amazonaws.com Version: "2012-10-17" Path: / Policies: - PolicyName: !Sub EXAMPLE-CdPlCreateUpdatePolicyLMBD-${SubName} PolicyDocument: Version: 2012-10-17 Statement: - Action: "*" Effect: Allow Resource: "*" # ------------------------------------------------------------# # CodePipeline Deploy Create Update Action Role (IAM) # ------------------------------------------------------------# CodePipelineDeployCreateUpdateActionRoleLMBD: Type: AWS::IAM::Role Properties: RoleName: !Sub EXAMPLE-CdPlCreateUpdateActionRoleLMBD-${SubName} AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: AWS: Fn::Join: - "" - - "arn:" - Ref: AWS::Partition - ":iam::" - Ref: AWS::AccountId - :root Version: "2012-10-17" Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AWSCloudFormationFullAccess Policies: - PolicyName: !Sub EXAMPLE-CdPlCreateUpdatePolicyLMBD-${SubName} PolicyDocument: Version: 2012-10-17 Statement: - Action: iam:PassRole Effect: Allow Resource: !GetAtt CodePipelineDeployCreateUpdateRoleLMBD.Arn - Action: - s3:GetBucket* - s3:GetObject* - s3:List* Effect: Allow Resource: - !Sub arn:aws:s3:::${S3BucketArtifact} - !Sub arn:aws:s3:::${S3BucketArtifact}/* DependsOn: - CodePipelineDeployCreateUpdateRoleLMBD - S3BucketArtifact # ------------------------------------------------------------# # EventBridge Rule for Starting CodePipeline # ------------------------------------------------------------# EventBridgeRuleStartCodePipelineLMBD: Type: AWS::Events::Rule Properties: Name: !Sub EXAMPLE-StartCpRuleLMBD-${SubName} Description: !Sub This rule starts CodePipeline for EXAMPLE-${SubName} LMBD when its source code in CodeCommit is changed. EventBusName: !Sub "arn:aws:events:${AWS::Region}:${AWS::AccountId}:event-bus/default" EventPattern: source: - "aws.codecommit" detail-type: - "CodeCommit Repository State Change" resources: - !GetAtt CodeCommitRepoLMBD.Arn detail: event: - referenceCreated - referenceUpdated referenceType: - branch referenceName: - master RoleArn: !GetAtt EventBridgeRuleStartCpRoleLMBD.Arn State: ENABLED Targets: - Arn: !Sub "arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:${CodePipelineLMBD}" Id: !Sub Target-EXAMPLE-CodePipelineLMBD-${SubName} RoleArn: !GetAtt EventBridgeRuleStartCpRoleLMBD.Arn DependsOn: - EventBridgeRuleStartCpRoleLMBD # ------------------------------------------------------------# # EventBridge Rule Start CodePipeline Role (IAM) # ------------------------------------------------------------# EventBridgeRuleStartCpRoleLMBD: Type: AWS::IAM::Role Properties: RoleName: !Sub EXAMPLE-EventBridgeRuleStartCpRoleLMBD-${SubName} Description: !Sub This role allows EventBridge to start EXAMPLE-${SubName} LMBD CodePipeline. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - events.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: !Sub EXAMPLE-EventBridgeRuleStartCpRolePolicyLMBD-${SubName} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "codepipeline:StartPipelineExecution" Resource: - !Sub "arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:${CodePipelineLMBD}" DependsOn: - CodePipelineLMBD # ------------------------------------------------------------# # CodeBuild Project # ------------------------------------------------------------# CodeBuildProjectLMBD: Type: AWS::CodeBuild::Project Properties: Name: !Sub EXAMPLE-${SubName}-BP-LMBD Description: !Sub The build project for EXAMPLE-${SubName} LMBD. ResourceAccessRole: !GetAtt CodeBuildResourceAccessRoleLMBD.Arn ServiceRole: !GetAtt CodeBuildServiceRoleLMBD.Arn ConcurrentBuildLimit: 1 Visibility: PRIVATE Source: Type: CODEPIPELINE SourceVersion: refs/heads/master Environment: Type: LINUX_CONTAINER ComputeType: BUILD_GENERAL1_SMALL Image: "aws/codebuild/amazonlinux2-x86_64-standard:4.0" ImagePullCredentialsType: CODEBUILD PrivilegedMode: true EnvironmentVariables: - Name: AWS_DEFAULT_REGION Type: PLAINTEXT Value: !Sub ${AWS::Region} - Name: AWS_ACCOUNT_ID Type: PLAINTEXT Value: !Sub ${AWS::AccountId} - Name: IMAGE_REPO_NAME Type: PLAINTEXT Value: !Ref EcrRepositoryLMBD TimeoutInMinutes: 30 QueuedTimeoutInMinutes: 60 Artifacts: Type: CODEPIPELINE Cache: Type: NO_CACHE LogsConfig: CloudWatchLogs: GroupName: !Sub /aws/codebuild/EXAMPLE-${SubName}-LMBD Status: ENABLED S3Logs: EncryptionDisabled: true Location: !Sub arn:aws:s3:::${S3BucketLogs}/codebuildBuildlog Status: ENABLED Tags: - Key: Cost Value: !Sub EXAMPLE-${SubName} DependsOn: - EcrRepositoryLMBD - CodeBuildResourceAccessRoleLMBD - CodeBuildServiceRoleLMBD # ------------------------------------------------------------# # CodeBuild Resource Access Role (IAM) # ------------------------------------------------------------# CodeBuildResourceAccessRoleLMBD: Type: AWS::IAM::Role Properties: RoleName: !Sub EXAMPLE-CodeBuildResourceAccessRoleLMBD-${SubName} Description: This role allows CodeBuild to access CloudWatch Logs and Amazon S3 artifacts for the project's builds. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - codebuild.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: !Sub EXAMPLE-CodeBuildResourceAccessRolePolicyLMBD-${SubName} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "logs:CreateLogGroup" - "logs:CreateLogStream" - "logs:PutLogEvents" Resource: - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/EXAMPLE-${SubName}-LMBD" - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/EXAMPLE-${SubName}-LMBD:*" - Effect: Allow Action: - "s3:PutObject" - "s3:GetObject" - "s3:GetObjectVersion" - "s3:GetBucketAcl" - "s3:GetBucketLocation" Resource: - !Sub arn:aws:s3:::${S3BucketLogs} - !Sub arn:aws:s3:::${S3BucketLogs}/* # ------------------------------------------------------------# # CodeBuild Service Role (IAM) # ------------------------------------------------------------# CodeBuildServiceRoleLMBD: Type: AWS::IAM::Role Properties: RoleName: !Sub EXAMPLE-CodeBuildServiceRoleLMBD-${SubName} Description: This role allows CodeBuild to interact with dependant AWS services. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - codebuild.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPowerUser Policies: - PolicyName: !Sub EXAMPLE-CodeBuildServiceRolePolicyLMBD-${SubName} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "codecommit:GitPull" Resource: !GetAtt CodeCommitRepoLMBD.Arn - Effect: Allow Action: - "ssm:GetParameters" Resource: - !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/EXAMPLE_${SubName}_*" - Effect: Allow Action: - "s3:*" Resource: - !Sub arn:aws:s3:::${S3BucketArtifact} - !Sub arn:aws:s3:::${S3BucketArtifact}/* - !Sub arn:aws:s3:::${S3BucketLogs} - !Sub arn:aws:s3:::${S3BucketLogs}/* - Effect: Allow Action: - "logs:CreateLogGroup" - "logs:CreateLogStream" - "logs:PutLogEvents" Resource: - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/EXAMPLE-${SubName}-LMBD" - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/EXAMPLE-${SubName}-LMBD:*" - Effect: Allow Action: - "codebuild:CreateReportGroup" - "codebuild:CreateReport" - "codebuild:UpdateReport" - "codebuild:BatchPutTestCases" - "codebuild:BatchPutCodeCoverages" Resource: - !Sub "arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:report-group/EXAMPLE-${SubName}*" DependsOn: - CodeCommitRepoLMBD - S3BucketArtifact - S3BucketLogs
※ IAM ロールの権限が一部適当 (権限が多すぎ) な部分があります。申し訳ありませんが適宜変更下さいませ。
AWS CloudFormation テンプレート (AWS コンテナ Lambda 関数デプロイ用)
- Cfn_LambdaContainer.yml
AWSTemplateFormatVersion: 2010-09-09 Description: The CloudFormation template that creates a Lambda function on container and a relevant IAM role. # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: SubName: Type: String Description: System sub name of EXAMPLE. (e.g. prod, test or your name) Default: yourname MaxLength: 10 MinLength: 1 ImageTag: Type: String Description: The image tag of container in ECR. This is accepted from CodePipeline. Default: latest MaxLength: 50 MinLength: 1 Resources: # ------------------------------------------------------------# # Lambda TestInvocation Role (IAM) # ------------------------------------------------------------# LambdaTestInvocationRole: Type: AWS::IAM::Role Properties: RoleName: !Sub EXAMPLE-LambdaTestInvocationRole-${SubName} Description: This role allows Lambda functions to invoke Test. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess # ------------------------------------------------------------# # Lambda # ------------------------------------------------------------# LambdaTest: Type: AWS::Lambda::Function Properties: FunctionName: !Sub EXAMPLE-getPythonVersion-${SubName} Description: !Sub Lambda Function to get python version for EXAMPLE-${SubName} PackageType: Image Timeout: 30 MemorySize: 128 EphemeralStorage: Size: 512 Architectures: - x86_64 Role: !GetAtt LambdaTestInvocationRole.Arn Tags: - Key: Cost Value: !Sub EXAMPLE-${SubName} Code: ImageUri: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/example-get-python-version-${SubName}:${ImageTag} DependsOn: - LambdaTestInvocationRole