コラム
こんにちは、クラウドCoEの熊谷です。
今回は「Lambdaのマルチアカウントデプロイ」と題し、テスト環境と本番環境とでAWSアカウントを分けるような運用環境において、テスト環境で構築したLambdaを本番環境にデプロイする方法をご紹介します。
構築編となる今回は、利用するCloudFormation(以下、CFn)テンプレートの解説をしつつ、どんどん構築していこうと思います。
構築の流れ
今回は4つのCFnテンプレートを使い、テスト環境と本番環境に対して交互に実行していきます。
前工程で作成したAWSリソースを後の工程で参照しているため、必ずこの順序でテンプレートを実行する必要があります。
なお本コラムではCloud9でLambdaを新規作成する手順やCodeCommitとCloud9の連携については説明を省略いたしますのでご了承ください。
[作業1]テスト環境にCodePipelineを構築!
[作業1]テンプレート 1-stg
AWSTemplateFormatVersion: 2010-09-09
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: STG Environment Parameter
Parameters:
- RepositoryName
- BuildProjectName
- STGPipelineName
- BucketName
- Label:
default: Prod Environment Parameter
Parameters:
- ProdPipelineName
- ProdAccountID
Parameters:
ProdAccountID:
Type : String
RepositoryName:
Type : String
BuildProjectName:
Type : String
STGPipelineName:
Type : String
BucketName:
Type: String
ProdPipelineName:
Type : String
Resources:
# ------------------------------------------------------------#
# EventBridge IAM Role/IAM Policy
# ------------------------------------------------------------#
IAMPolicyForEventBridge:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: !Sub STGPolicyForEventBridge-${STGPipelineName}
Roles:
- !Ref IAMRoleForEventBridge
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- codepipeline:StartPipelineExecution
Resource:
- !Sub arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:${STGPipelineName}
IAMRoleForEventBridge:
Type: AWS::IAM::Role
Properties:
RoleName: STGRoleForEventBridgeTriggerdBySTGBranchEvnet
Path: /service-role/
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service: events.amazonaws.com
# ------------------------------------------------------------#
# EventBridgeTriggerdByMasterBranchEvnet IAM Role/IAM Policy
# ------------------------------------------------------------#
IAMPolicyForEventBridgeTriggerdByMasterBranchEvnet:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: !Sub STGPolicyForEventBridge-${ProdPipelineName}
Roles:
- !Ref IAMRoleForEventBridgeTriggerdByMasterBranchEvnet
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- events:PutEvents
Resource:
- !Sub arn:aws:events:${AWS::Region}:${ProdAccountID}:event-bus/default
IAMRoleForEventBridgeTriggerdByMasterBranchEvnet:
Type: AWS::IAM::Role
Properties:
RoleName: STGRoleForEventBridgeTriggerdByMasterBranchEvnet
Path: /service-role/
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service: events.amazonaws.com
# ------------------------------------------------------------#
# CodeBuild IAM Role/IAM Policy
# ref. https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/auth-and-access-control-permissions-reference.html
# ------------------------------------------------------------#
IAMPolicyForCodeBuild:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: !Sub STGPolicyForCodeBuild-${STGPipelineName}
Roles:
- !Ref IAMRoleForCodeBuild
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: CloudWatchLogsPolicy
Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildProject}
- !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildProject}:*
- Sid: CodeCommitPull
Effect: Allow
Action:
- codecommit:GitPull
Resource: !Sub arn:aws:codecommit:${AWS::Region}:${AWS::AccountId}:${RepositoryName}
- Sid: BuildStageArtifactPushPolicy
Effect: Allow
Action:
- s3:PutObject
Resource:
- !Join ['', ['arn:aws:s3:::', !Ref ArtifactBucket, /*]]
- Sid: SourceStageArtifactGetPolicy
Effect: Allow
Action:
- s3:GetBucketAcl
- s3:GetBucketLocation
Resource:
- !GetAtt ArtifactBucket.Arn
- Sid: GetArtifactPolicy
Effect: Allow
Action:
- s3:GetObject
- s3:GetObjectVersion
Resource:
- !Join ['', ['arn:aws:s3:::', !Ref ArtifactBucket, /*]]
- Sid: AllowUseCMK
Effect: Allow
Action:
- kms:GenerateDataKey
- kms:GenerateDataKeyWithoutPlaintext
- kms:DescribeKey
- kms:Encrypt
- kms:Decrypt
Resource:
- !GetAtt Key.Arn
IAMRoleForCodeBuild:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub STGRoleForCodeBuild-${STGPipelineName}
Path: /service-role/
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service: codebuild.amazonaws.com
# ------------------------------------------------------------#
# Deploy Stage IAM Role/IAM Policy
# ------------------------------------------------------------#
IAMPolicyForDeployStage:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: !Sub STGPolicyForDeploy-${STGPipelineName}
Roles:
- !Ref IAMRoleForDeployStage
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: LambdaDeployPolicy
Effect: Allow
Action:
- lambda:*
Resource: "*"
- Sid: APIGatewayPolicy
Effect: Allow
Action:
- apigateway:*
Resource: "*"
- Sid: CloudFormationCreateChangeSetPolicy
Effect: Allow
Action:
- cloudformation:CreateChangeSet
Resource: "*"
- Sid: IAMPolicy
Effect: Allow
Action:
- iam:GetRole
- iam:CreateRole
- iam:DeleteRole
- iam:PutRolePolicy
- iam:AttachRolePolicy
- iam:DeleteRolePolicy
- iam:DetachRolePolicy
- iam:PassRole
Resource: "*"
- Sid: GetArtifactStorePolicy
Effect: Allow
Action:
- s3:GetBucketLocation
- s3:GetBucketVersioning
- s3:GetBucketAcl
Resource:
- !GetAtt ArtifactBucket.Arn
- Sid: GetArtifactPolicy
Effect: Allow
Action:
- s3:GetObject
- s3:GetObjectVersion
Resource:
- !Join ['', ['arn:aws:s3:::', !Ref ArtifactBucket, /*]]
IAMRoleForDeployStage:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub STGRoleForDeploy-${STGPipelineName}
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service: cloudformation.amazonaws.com
Path: /
# IAMPolicy for CodePipeline
IAMPolicyForCodePipeline:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: !Sub STGPolicyForCodePipeline-${STGPipelineName}
Roles:
- !Ref IAMRoleFoCodePipeline
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- iam:PassRole
Resource: "*"
Condition:
StringEqualsIfExists:
iam:PassedToService:
- cloudformation.amazonaws.com
- Sid: CodeCommitPolicy
Effect: Allow
Action:
- codecommit:CancelUploadArchive
- codecommit:GetBranch
- codecommit:GetCommit
- codecommit:GetUploadArchiveStatus
- codecommit:UploadArchive
Resource:
- !Sub arn:aws:codecommit:${AWS::Region}:${AWS::AccountId}:${RepositoryName}
- Sid: CodeBuildPolicy
Effect: Allow
Action:
- codebuild:BatchGetBuilds
- codebuild:StartBuild
- codebuild:StopBuild
- codebuild:RetryBuild
Resource:
- !Sub arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:project/${CodeBuildProject}
- Sid: LambdaPolicy
Effect: Allow
Action:
- lambda:InvokeFunction
- lambda:ListFunctions
Resource: "*"
- Sid: CloudFormationDeployPolicy
Effect: Allow
Action:
- cloudformation:CreateStack
- cloudformation:DeleteStack
- cloudformation:DescribeStacks
- cloudformation:UpdateStack
- cloudformation:CreateChangeSet
- cloudformation:DeleteChangeSet
- cloudformation:DescribeChangeSet
- cloudformation:ExecuteChangeSet
- cloudformation:SetStackPolicy
- cloudformation:ValidateTemplate
Resource: "*"
- Sid: SourceStageArtifactPushPolicy
Effect: Allow
Action:
- s3:PutObject
Resource:
- !Join ['', ['arn:aws:s3:::', !Ref ArtifactBucket, /*]]
- Sid: SourceStageArtifactGetPolicy
Effect: Allow
Action:
- s3:GetBucketAcl
- s3:GetBucketLocation
Resource:
- !GetAtt ArtifactBucket.Arn
- Sid: GetArtifactStorePolicy
Effect: Allow
Action:
- s3:GetObject
- s3:GetObjectVersion
Resource:
- !Join ['', ['arn:aws:s3:::', !Ref ArtifactBucket, /*]]
IAMRoleFoCodePipeline:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub STGRoleForCodePipeline-${STGPipelineName}
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service: codepipeline.amazonaws.com
# ------------------------------------------------------------#
# CodeCommit
# ------------------------------------------------------------#
CodeCommitRepository:
Type: AWS::CodeCommit::Repository
Properties:
RepositoryName: !Ref RepositoryName
RepositoryDescription: !Sub store ${RepositoryName} source
# ------------------------------------------------------------#
# CodeBuild
# ------------------------------------------------------------#
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Name: !Ref BuildProjectName
Source:
BuildSpec: buildspec.yml
Type: CODEPIPELINE
Artifacts:
Type: CODEPIPELINE
EncryptionKey: !GetAtt Key.Arn
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/standard:4.0
Type: LINUX_CONTAINER
EnvironmentVariables:
- Name: BUCKET_NAME
Type: PLAINTEXT
Value: !Ref BucketName
ServiceRole: !GetAtt IAMRoleForCodeBuild.Arn
# ------------------------------------------------------------#
# CpdePipeline
# ------------------------------------------------------------#
CodePipelineForLambda:
Type: AWS::CodePipeline::Pipeline
Properties:
ArtifactStore:
Location: !Ref ArtifactBucket
Type: S3
EncryptionKey:
Id: !GetAtt Key.Arn
Type: KMS
Name: !Ref STGPipelineName
RoleArn: !GetAtt IAMRoleFoCodePipeline.Arn
Stages:
- Name: Source
Actions:
- Name: Commit
ActionTypeId:
Category: Source
Owner: AWS
Version: 1
Provider: CodeCommit
Configuration:
RepositoryName: !Ref RepositoryName
BranchName: stg
RunOrder: 1
OutputArtifacts:
- Name: SourceArtifact
- Name: Build
Actions:
- Name: Build
ActionTypeId:
Category: Build
Owner: AWS
Version: 1
Provider: CodeBuild
RunOrder: 1
Configuration:
ProjectName: !Ref CodeBuildProject
InputArtifacts:
- Name: SourceArtifact # SourceステージのOutputArtifactsの名称と揃える
OutputArtifacts:
- Name: BuildArtifact
- Name: Deploy
Actions:
- Name: Deploy
InputArtifacts:
- Name: BuildArtifact # BuildステージのOutputArtifactsの名称と揃える
ActionTypeId:
Category: Deploy
Owner: AWS
Version: 1
Provider: CloudFormation
Configuration:
ActionMode: CHANGE_SET_REPLACE
Capabilities: CAPABILITY_IAM,CAPABILITY_AUTO_EXPAND,CAPABILITY_NAMED_IAM
ChangeSetName: lambda-pipeline-changeset
StackName: lambda-pipeline-changeset
TemplatePath: 'BuildArtifact::packaged-template.yaml' # CodeBuildのbuildspec.ymlで出力した成果物の名称
RoleArn: !GetAtt IAMRoleForDeployStage.Arn
RunOrder: 1
# ------------------------------------------------------------#
# EventBridge
# ref. https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/pipelines-trigger-source-repo-changes-cfn.html
# ------------------------------------------------------------#
EventBridgeTriggerdByCodeCommitSTGBranchMerge:
Type: AWS::Events::Rule
Properties:
Description: !Sub Invoking STG CodePipeline ${RepositoryName}
Name: !Sub EventBridgeRule-STG-CodePipeline-${RepositoryName}
EventPattern:
source:
- aws.codecommit
resources:
- !Sub arn:aws:codecommit:${AWS::Region}:${AWS::AccountId}:${RepositoryName}
detail:
event:
- referenceCreated
- referenceUpdated
referenceType:
- branch
referenceName:
- stg
detail-type:
- CodeCommit Repository State Change
Targets:
- Id: codepipeline
RoleArn: !GetAtt IAMRoleForEventBridge.Arn
Arn: !Sub arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:${STGPipelineName}
EventBridgeTriggerdByCodeCommitProdBranchMerge:
Type: AWS::Events::Rule
Properties:
Description: !Sub Invoking Prod CodePipeline ${RepositoryName}
Name: !Sub EventBridgeRule-Prod-CodePipeline-${RepositoryName}
EventPattern:
source:
- aws.codecommit
resources:
- !Sub arn:aws:codecommit:${AWS::Region}:${AWS::AccountId}:${RepositoryName}
detail:
event:
- referenceCreated
- referenceUpdated
referenceType:
- branch
referenceName:
- master
detail-type:
- CodeCommit Repository State Change
Targets:
- Id: prod-event-bus
RoleArn: !GetAtt IAMRoleForEventBridgeTriggerdByMasterBranchEvnet.Arn
Arn: !Sub arn:aws:events:${AWS::Region}:${ProdAccountID}:event-bus/default
# ------------------------------------------------------------#
# KMS
# ------------------------------------------------------------#
Key:
Type: AWS::KMS::Key
Properties:
Description: CodePipeline CMK
KeyPolicy:
Version: 2012-10-17
Id: key-default-1
Statement:
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS:
- !Sub arn:aws:iam::${AWS::AccountId}:root
Action: kms:*
Resource: "*"
- Sid: Allow administration of the key
Effect: Allow
Principal:
AWS:
- !Sub arn:aws:iam::${AWS::AccountId}:root
Action:
- kms:Create*
- kms:Describe*
- kms:Enable*
- kms:List*
- kms:Put*
- kms:Update*
- kms:Revoke*
- kms:Disable*
- kms:Get*
- kms:Delete*
- kms:ScheduleKeyDeletion
- kms:CancelKeyDeletion
Resource: "*"
- Sid: Allow use of the key
Effect: Allow
Principal:
AWS:
- !GetAtt IAMRoleFoCodePipeline.Arn
- !GetAtt IAMRoleForCodeBuild.Arn
- !GetAtt IAMRoleForDeployStage.Arn
Action:
- kms:DescribeKey
- kms:Encrypt
- kms:Decrypt
- kms:ReEncrypt*
- kms:GenerateDataKey
- kms:GenerateDataKeyWithoutPlaintext
Resource: "*"
- Sid: Allow attachment of persistent resources
Effect: Allow
Principal:
AWS:
- !GetAtt IAMRoleFoCodePipeline.Arn
- !GetAtt IAMRoleForCodeBuild.Arn
- !GetAtt IAMRoleForDeployStage.Arn
Action:
- kms:CreateGrant
- kms:ListGrants
- kms:RevokeGrant
Resource: "*"
Condition:
Bool:
kms:GrantIsForAWSResource: true
Alias:
Type: AWS::KMS::Alias
Properties:
AliasName: alias/CodePipelineArtifact
TargetKeyId:
Ref: Key
# ------------------------------------------------------------#
# S3Bucket
# ------------------------------------------------------------#
ArtifactBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketName
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
LifecycleConfiguration:
Rules:
- ExpirationInDays: 90
Id: !Sub ${BucketName}-LifeCycle
Status: Enabled
S3ArtifactBucketPolicy:
Type: AWS::S3::BucketPolicy
Description: Amazon S3 bucket policy for CMK
Properties:
Bucket: !Ref ArtifactBucket
PolicyDocument:
Statement:
- Sid: DenyAccessWithoutUsingCMK
Action:
- s3:PutObject
Effect: Deny
Principal: "*"
Resource:
- !Sub arn:aws:s3:::${ArtifactBucket}/*
Condition:
StringNotLikeIfExists:
{"s3:x-amz-server-side-encryption-aws-kms-key-id": !GetAtt Key.Arn}
- Sid: DenyHTTPAccessPolicy
Action:
- s3:*
Effect: Deny
Principal: "*"
Resource:
- !Sub arn:aws:s3:::${ArtifactBucket}/*
Condition:
Bool:
aws:SecureTransport: false
- Sid: S3GetPutPolicy
Action:
- s3:Get*
- s3:Put*
Effect: Allow
Principal:
AWS:
- !Sub arn:aws:iam::${AWS::AccountId}:root
Resource:
- !Sub arn:aws:s3:::${ArtifactBucket}/*
- Sid: S3ListPolicy
Action:
- s3:ListBucket
Effect: Allow
Principal:
AWS:
- !Sub arn:aws:iam::${AWS::AccountId}:root
Resource:
- !Sub arn:aws:s3:::${ArtifactBucket}
Version: 2012-10-17
[作業1]テンプレートの補足 2つのEventBridge
1-stgテンプレートでは2つのEventBridgeを構築します。
- stgブランチのイベントを拾うEventBridge
- masterブランチのイベントを拾うEventBridge
1つ目のEventBridgeはstgブランチへのマージイベントを拾ってテスト環境のCodePipelineを動かします。
2つ目のEventBridgeはmasterブランチのイベントを拾い、本番CodePipelineを起動するためのものです。
両者のテンプレート上の記述の違いはイベントパターンのreferenceNameとターゲットです。
stgブランチのイベントを拾うEventBridgeの記述例
EventBridgeTriggerdByCodeCommitSTGBranchMerge:
Type: AWS::Events::Rule
Properties:
###省略###
EventPattern:
source:
- aws.codecommit
resources:
- !Sub arn:aws:codecommit:${AWS::Region}:${AWS::AccountId}:${RepositoryName}
detail:
event:
- referenceCreated
- referenceUpdated
referenceType:
- branch
referenceName:
- stg
detail-type:
- CodeCommit Repository State Change
Targets:
- Id: codepipeline
RoleArn: !GetAtt IAMRoleForEventBridge.Arn
Arn: !Sub arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:${STGPipelineName} #テスト環境のCodePipeline
本番環境のCodePipelineを起動させたいとしても、異なるAWSアカウントのCodePipelineを直接ターゲットにしたところで動いてくれません。
よって本番環境のEventBridgeを動かしてくれるEventBusをターゲットに設定します。
masterブランチのイベントを拾うEventBridgeの記述例
EventBridgeTriggerdByCodeCommitProdBranchMerge:
Type: AWS::Events::Rule
Properties:
###省略###
EventPattern:
source:
- aws.codecommit
resources:
- !Sub arn:aws:codecommit:${AWS::Region}:${AWS::AccountId}:${RepositoryName}
detail:
event:
- referenceCreated
- referenceUpdated
referenceType:
- branch
referenceName:
- master
detail-type:
- CodeCommit Repository State Change
Targets:
- Id: prod-event-bus
RoleArn: !GetAtt IAMRoleForEventBridgeTriggerdByMasterBranchEvnet.Arn
Arn: !Sub arn:aws:events:${AWS::Region}:${ProdAccountID}:event-bus/default #本番環境のEvnet Bus
masterブランチイベント用のEventBridgeのサービスロールでは、本番環境のEvent Busを動かすための権限が必要です。
master用EventBridgeのサービスロールにアタッチするIAMポリシー
IAMPolicyForEventBridgeTriggerdByMasterBranchEvnet:
Type: AWS::IAM::ManagedPolicy
Properties:
###省略###
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- events:PutEvents
Resource:
- !Sub arn:aws:events:${AWS::Region}:${ProdAccountID}:event-bus/default
[作業1]テンプレートの補足 DeployStageのサービスロール
今回はLambdaとAPI Gatewayをデプロイするため、サービスロールに両サービスの権限を付与しています。
DeployStageのサービスロール
IAMPolicyForDeployStage:
Type: AWS::IAM::ManagedPolicy
Properties:
###省略###
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: LambdaDeployPolicy
Effect: Allow
Action:
- lambda:*
Resource: "*"
- Sid: APIGatewayPolicy
Effect: Allow
Action:
- apigateway:*
Resource: "*"
SAMではEventBridge RuleやSNS、Step Functionもデプロイ出来ますので、利用したいサービスに応じてDeploy Stageの権限を変更しましょう。
SAMでデプロイ可能なAWSサービスに関しては以下をご参照ください。
[作業1]テンプレートのパラメータ
Pipeline名やBuildプロジェクト名を自由に設定できるようにパラメータにしました。
スタックが正常に作成されるとCodePipelineが起動しますが、まだCodeCommitにブランチが作成されていない状態ですのでこけます。
気にせず次の工程に進みましょう。
[作業2]本番環境でIAMロール・CMK・S3バケットを作成!
作業2では本番環境のCodePipelineやCodeBuildのサービスロールや、成果物暗号化用のCMK、成果物格納用S3バケットを作成します。
これらのAWSサービスのARNが作業3で必要になります。
[作業2]テンプレート 2-prod
AWSTemplateFormatVersion: 2010-09-09
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: STG Environment Parameter
Parameters:
- STGAccountId
- Label:
default: Prod Environment Parameter
Parameters:
- BuildProjectName
- PipelineName
- BucketName
Parameters:
STGAccountId:
Description: Repository Account ID
MaxLength: 12
MinLength: 12
Type: String
BucketName:
Type: String
BuildProjectName:
Type : String
PipelineName:
Type : String
Resources:
# ------------------------------------------------------------#
# CodeBuild IAM Role/IAM Policy
# ref. https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/auth-and-access-control-permissions-reference.html
# ------------------------------------------------------------#
IAMPolicyForCodeBuild:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: !Sub ProdPolicyForCodeBuild-${PipelineName}
Roles:
- !Ref IAMRoleForCodeBuild
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: CloudWatchLogsPolicy
Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${BuildProjectName}
- !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${BuildProjectName}:*
- Sid: BuildStageArtifactPushPolicy
Effect: Allow
Action:
- s3:PutObject
Resource:
- !Join ['', ['arn:aws:s3:::', !Ref ArtifactBucket, /*]]
- Sid: SourceStageArtifactGetPolicy
Effect: Allow
Action:
- s3:GetBucketAcl
- s3:GetBucketLocation
Resource:
- !GetAtt ArtifactBucket.Arn
- Sid: GetArtifactPolicy
Effect: Allow
Action:
- s3:GetObject
- s3:GetObjectVersion
Resource:
- !Join ['', ['arn:aws:s3:::', !Ref ArtifactBucket, /*]]
IAMRoleForCodeBuild:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ProdRoleForCodeBuild-${PipelineName}
Path: /service-role/
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service: codebuild.amazonaws.com
# ------------------------------------------------------------#
# Deploy Stage IAM Role/IAM Policy
# ------------------------------------------------------------#
IAMPolicyForDeployStage:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: !Sub ProdPolicyForDeploy-${PipelineName}
Roles:
- !Ref IAMRoleForDeployStage
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: LambdaDeployPolicy
Effect: Allow
Action:
- lambda:*
Resource: "*"
- Sid: APIGatewayPolicy
Effect: Allow
Action:
- apigateway:*
Resource: "*"
- Sid: CloudFormationCreateChangeSetPolicy
Effect: Allow
Action:
- cloudformation:CreateChangeSet
Resource: "*"
- Sid: IAMPolicy
Effect: Allow
Action:
- iam:GetRole
- iam:CreateRole
- iam:DeleteRole
- iam:PutRolePolicy
- iam:AttachRolePolicy
- iam:DeleteRolePolicy
- iam:DetachRolePolicy
- iam:PassRole
Resource: "*"
- Sid: GetArtifactStorePolicy
Effect: Allow
Action:
- s3:GetBucketLocation
- s3:GetBucketVersioning
- s3:GetBucketAcl
Resource:
- !GetAtt ArtifactBucket.Arn
- Sid: GetArtifactPolicy
Effect: Allow
Action:
- s3:GetObject
- s3:GetObjectVersion
Resource:
- !Join ['', ['arn:aws:s3:::', !Ref ArtifactBucket, /*]]
IAMRoleForDeployStage:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ProdRoleForDeploy-${PipelineName}
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service: cloudformation.amazonaws.com
Path: /
# IAMPolicy for CodePipeline
IAMPolicyForCodePipeline:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: !Sub ProdPolicyForCodePipeline-${PipelineName}
Roles:
- !Ref IAMRoleFoCodePipeline
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- iam:PassRole
Resource: "*"
Condition:
StringEqualsIfExists:
iam:PassedToService:
- cloudformation.amazonaws.com
- Sid: CodeBuildPolicy
Effect: Allow
Action:
- codebuild:BatchGetBuilds
- codebuild:StartBuild
- codebuild:StopBuild
- codebuild:RetryBuild
Resource:
- !Sub arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:project/${BuildProjectName}
- Sid: LambdaPolicy
Effect: Allow
Action:
- lambda:InvokeFunction
- lambda:ListFunctions
Resource: "*"
- Sid: CloudFormationDeployPolicy
Effect: Allow
Action:
- cloudformation:CreateStack
- cloudformation:DeleteStack
- cloudformation:DescribeStacks
- cloudformation:UpdateStack
- cloudformation:CreateChangeSet
- cloudformation:DeleteChangeSet
- cloudformation:DescribeChangeSet
- cloudformation:ExecuteChangeSet
- cloudformation:SetStackPolicy
- cloudformation:ValidateTemplate
Resource: "*"
- Sid: SourceStageArtifactPushPolicy
Effect: Allow
Action:
- s3:PutObject
Resource:
- !Join ['', ['arn:aws:s3:::', !Ref ArtifactBucket, /*]]
- Sid: SourceStageArtifactGetPolicy
Effect: Allow
Action:
- s3:GetBucketAcl
- s3:GetBucketLocation
Resource:
- !GetAtt ArtifactBucket.Arn
- Sid: STGAccountAssumeRole
Effect: Allow
Action:
- sts:AssumeRole
Resource:
- !Sub arn:aws:iam::${STGAccountId}:role/*
- Sid: GetArtifactStorePolicy
Effect: Allow
Action:
- s3:GetObject
- s3:GetObjectVersion
Resource:
- !Join ['', ['arn:aws:s3:::', !Ref ArtifactBucket, /*]]
IAMRoleFoCodePipeline:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ProdRoleForCodePipeline-${PipelineName}
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service: codepipeline.amazonaws.com
# ------------------------------------------------------------#
# KMS
# ref. https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/key-policy-modifying-external-accounts.html
# ------------------------------------------------------------#
Key:
Type: AWS::KMS::Key
Properties:
Description: CodePipeline CMK
KeyPolicy:
Version: 2012-10-17
Id: key-default-1
Statement:
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS:
- !Sub arn:aws:iam::${AWS::AccountId}:root
Action: kms:*
Resource: "*"
- Sid: Allow administration of the key
Effect: Allow
Principal:
AWS:
- !Sub arn:aws:iam::${AWS::AccountId}:root
- !Sub arn:aws:iam::${STGAccountId}:root
Action:
- kms:Create*
- kms:Describe*
- kms:Enable*
- kms:List*
- kms:Put*
- kms:Update*
- kms:Revoke*
- kms:Disable*
- kms:Get*
- kms:Delete*
- kms:ScheduleKeyDeletion
- kms:CancelKeyDeletion
Resource: "*"
- Sid: Allow use of the key
Effect: Allow
Principal:
AWS:
- !Sub arn:aws:iam::${STGAccountId}:root
- !GetAtt IAMRoleFoCodePipeline.Arn
- !GetAtt IAMRoleForCodeBuild.Arn
- !GetAtt IAMRoleForDeployStage.Arn
Action:
- kms:DescribeKey
- kms:Encrypt
- kms:Decrypt
- kms:ReEncrypt*
- kms:GenerateDataKey
- kms:GenerateDataKeyWithoutPlaintext
Resource: "*"
- Sid: Allow attachment of persistent resources
Effect: Allow
Principal:
AWS:
- !Sub arn:aws:iam::${STGAccountId}:root
- !GetAtt IAMRoleFoCodePipeline.Arn
- !GetAtt IAMRoleForCodeBuild.Arn
- !GetAtt IAMRoleForDeployStage.Arn
Action:
- kms:CreateGrant
- kms:ListGrants
- kms:RevokeGrant
Resource: "*"
Condition:
Bool:
kms:GrantIsForAWSResource: true
Alias:
Type: AWS::KMS::Alias
Properties:
AliasName: alias/CodePipelineArtifact
TargetKeyId:
Ref: Key
# ------------------------------------------------------------#
# S3Bucket
# ------------------------------------------------------------#
ArtifactBucket:
Description: Amazon S3 bucket for AWS CodePipeline artifacts
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketName
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
LifecycleConfiguration:
Rules:
- ExpirationInDays: 90
Id: !Sub ${BucketName}-LifeCycle
Status: Enabled
S3ArtifactBucketPolicy:
Type: AWS::S3::BucketPolicy
Description: Amazon S3 bucket policy for Cross Account access
Properties:
Bucket: !Ref ArtifactBucket
PolicyDocument:
Statement:
- Sid: DenyAccessWithoutUsingCMK
Action:
- s3:PutObject
Effect: Deny
Principal: "*"
Resource:
- !Sub arn:aws:s3:::${ArtifactBucket}/*
Condition:
StringNotLikeIfExists:
{"s3:x-amz-server-side-encryption-aws-kms-key-id": !GetAtt Key.Arn}
- Sid: DenyHTTPAccessPolicy
Action:
- s3:*
Effect: Deny
Principal: "*"
Resource:
- !Sub arn:aws:s3:::${ArtifactBucket}/*
Condition:
Bool:
aws:SecureTransport: false
- Sid: CrossAccountS3GetPutPolicy
Action:
- s3:Get*
- s3:Put*
Effect: Allow
Principal:
AWS:
- !Sub arn:aws:iam::${STGAccountId}:root
Resource:
- !Sub arn:aws:s3:::${ArtifactBucket}/*
- Sid: CrossAccountS3ListPolicy
Action:
- s3:ListBucket
Effect: Allow
Principal:
AWS:
- !Sub arn:aws:iam::${STGAccountId}:root
Resource:
- !Sub arn:aws:s3:::${ArtifactBucket}
Version: 2012-10-17
Outputs:
KMS:
Description: Prod KMS
Export:
Name: PipelineKey
Value: !GetAtt Key.Arn
ArtifactBucketName:
Description: Prod S3Bucket
Export:
Name: ProdBucket
Value: !Ref ArtifactBucket
ArtifactBucketARN:
Description: Prod S3Bucket ARN
Export:
Name: ProdBucketARN
Value: !GetAtt ArtifactBucket.Arn
IAMRoleForCodeBuildARN:
Description: CodeBuild IAM Role ARN
Export:
Name: IAMRoleForCodeBuildARN
Value: !GetAtt IAMRoleForCodeBuild.Arn
IAMRoleForDeployStageARN:
Description: DeployStage IAM Role ARN
Export:
Name: IAMRoleForDeployStageARN
Value: !GetAtt IAMRoleForDeployStage.Arn
IAMRoleFoCodePipelineARN:
Description: CodePipeline IAM Role ARN
Export:
Name: IAMRoleFoCodePipelineARN
Value: !GetAtt IAMRoleFoCodePipeline.Arn
[作業2]テンプレートの補足 CodePipelineのサービスロール
作業2で作成するCode系のサービスのIAMロールの設定は、作業1でテスト環境用に作成したものとほぼ同じです。
違いは、本番環境CodePipelineのサービスロールにCodeCommitのpull権限等がないことと、テスト環境のIAMロールへのAssumeRole権限が設定されていることの2点になります。
「Lambdaのマルチアカウントデプロイ 設計編」でも触れましたが、テスト環境のCodeCommitのリポジトリからpullするためにはテスト環境のIAMロールを利用します。
<再掲>本番環境のCodePipelineがテスト環境のCodeCommitリポジトリにアクセスするイメージ
よって本番環境のCodePipelineにはテスト環境のActionロールを利用できる権限が必要です。
CodePipelineのサービスロールにアタッチする権限
IAMPolicyForCodePipeline:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: !Sub ProdPolicyForCodePipeline-${PipelineName}
Roles:
- !Ref IAMRoleFoCodePipeline
PolicyDocument:
Version: '2012-10-17'
Statement:
###省略###
- Sid: STGAccountAssumeRole
Effect: Allow
Action:
- sts:AssumeRole
Resource:
- !Sub arn:aws:iam::${STGAccountId}:role/*
[作業2]テンプレートのパラメータ
[作業3]テスト環境にActionロールを作成!
ではテスト環境に本番環境CodePipelineが利用するActionロールを作りましょう。
[作業3]テンプレート 3-stg
Actionロールには以下の権限が必要です。
- 本番環境のS3バケットにCodeCommitのソースをPut
- 本番環境のCMKを使って成果物を暗号化
- テスト環境のリポジトリの変更情報を取得
AWSTemplateFormatVersion: 2010-09-09
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: STG Environment Parameter
Parameters:
- RepositoryName
- Label:
default: Prod Environment Parameter
Parameters:
- ProductionAccountId
- ProductionS3BucketARN
- ProductionCmkArn
Parameters:
ProductionAccountId:
Description: Production Account ID
MaxLength: 12
MinLength: 12
Type: String
ProductionS3BucketARN:
Description: Production Account S3 Bucket ARN for Artifact
Type: String
ProductionCmkArn:
Description: Production Account CMK ARN
Type: String
RepositoryName:
Description: STG CodeCommit RepositoryName
Type: String
Resources:
# ------------------------------------------------------------#
# IAM Role
# ------------------------------------------------------------#
MultiAccountCodeCommitRole:
Type: AWS::IAM::Role
Properties:
RoleName: ProdCodePipelineActionRole
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
AWS:
- !Sub arn:aws:iam::${ProductionAccountId}:root
Action:
- sts:AssumeRole
Path: /
Policies:
- PolicyName: source
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- s3:PutObject
- s3:PutObjectAcl
Resource:
- !Sub ${ProductionS3BucketARN}/*
- Effect: Allow
Action:
- kms:DescribeKey
- kms:GenerateDataKey*
- kms:Encrypt
- kms:ReEncrypt*
- kms:Decrypt
Resource:
- !Ref ProductionCmkArn
- Effect: Allow
Action:
- codecommit:GetBranch
- codecommit:GetCommit
- codecommit:UploadArchive
- codecommit:GetUploadArchiveStatus
- codecommit:CancelUploadArchive
Resource:
- !Sub arn:aws:codecommit:ap-northeast-1:${AWS::AccountId}:${RepositoryName}
[作業3]テンプレートのパラメータ
[作業4]本番環境にCodePipelineを構築!
ではいよいよ本番環境のCodePipelineを構築します。CFnでの作業はこれが最後になります。
[作業4]テンプレート 4-prod
AWSTemplateFormatVersion: 2010-09-09
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: STG Environment Parameter
Parameters:
- STGCodeCommitIAMRole
- STGRepositoryName
- STGAccountId
- Label:
default: Prod Environment Parameter
Parameters:
- BuildProjectName
- PipelineName
Parameters:
BuildProjectName:
Type : String
PipelineName:
Type : String
STGCodeCommitIAMRole:
Type : String
STGRepositoryName:
Type : String
STGAccountId:
Description: Repository Account ID
MaxLength: 12
MinLength: 12
Type: String
Resources:
# ------------------------------------------------------------#
# EventBridge IAM Role/IAM Policy
# ------------------------------------------------------------#
IAMPolicyForEventBridge:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: !Sub ProdPolicyForEventBridge-${PipelineName}
Roles:
- !Ref IAMRoleForEventBridge
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- codepipeline:StartPipelineExecution
Resource:
- !Sub arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:${PipelineName}
IAMRoleForEventBridge:
Type: AWS::IAM::Role
Properties:
RoleName: ProdRoleForEventBridge
Path: /service-role/
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service: events.amazonaws.com
# ------------------------------------------------------------#
# CodeBuild
# ------------------------------------------------------------#
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Artifacts:
Type: CODEPIPELINE
EncryptionKey: !ImportValue PipelineKey
Name: !Ref BuildProjectName
Source:
BuildSpec: buildspec.yml
Type: CODEPIPELINE
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/standard:4.0
Type: LINUX_CONTAINER
EnvironmentVariables:
- Name: BUCKET_NAME
Type: PLAINTEXT
Value: !ImportValue ProdBucket
ServiceRole: !ImportValue IAMRoleForCodeBuildARN
# ------------------------------------------------------------#
# CodePipeline
# ------------------------------------------------------------#
CodePipelineForLambda:
Type: AWS::CodePipeline::Pipeline
Properties:
ArtifactStore:
Location: !ImportValue ProdBucket
Type: S3
EncryptionKey:
Id: !ImportValue PipelineKey
Type: KMS
Name: !Ref PipelineName
RoleArn: !ImportValue IAMRoleFoCodePipelineARN
Stages:
- Name: Source
Actions:
- Name: Commit
InputArtifacts: []
OutputArtifacts:
- Name: SourceArtifact
ActionTypeId:
Category: Source
Owner: AWS
Version: 1
Provider: CodeCommit
RoleArn: !Ref STGCodeCommitIAMRole
Configuration:
RepositoryName: !Ref STGRepositoryName
BranchName: master
PollForSourceChanges: false
RunOrder: 1
- Name: Build
Actions:
- Name: Build
ActionTypeId:
Category: Build
Owner: AWS
Version: 1
Provider: CodeBuild
RunOrder: 1
Configuration:
ProjectName: !Ref CodeBuildProject
InputArtifacts:
- Name: SourceArtifact
OutputArtifacts:
- Name: BuildArtifact
- Name: Deploy
Actions:
- Name: Deploy
InputArtifacts:
- Name: BuildArtifact
ActionTypeId:
Category: Deploy
Owner: AWS
Version: 1
Provider: CloudFormation
Configuration:
ActionMode: CHANGE_SET_REPLACE
Capabilities: CAPABILITY_IAM,CAPABILITY_AUTO_EXPAND,CAPABILITY_NAMED_IAM
ChangeSetName: lambda-pipeline-changeset
StackName: lambda-pipeline-changeset
TemplatePath: 'BuildArtifact::packaged-template.yaml' # CodeBuildのbuildspec.ymlで出力した成果物の名称
RoleArn: !ImportValue IAMRoleForDeployStageARN
RunOrder: 3
# ------------------------------------------------------------#
# EventBridge
# ref. https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/pipelines-trigger-source-repo-changes-cfn.html
# ------------------------------------------------------------#
EventBridgeTriggerdByCodeCommitMerge:
Type: AWS::Events::Rule
Properties:
Description: !Sub Invoking CodePipeline prod ${STGRepositoryName}
Name: !Sub EventBridgeRule-CodePipeline-Prod${STGRepositoryName}
EventPattern:
source:
- aws.codecommit
resources:
- !Sub arn:aws:codecommit:${AWS::Region}:${STGAccountId}:${STGRepositoryName}
detail:
event:
- referenceCreated
- referenceUpdated
referenceType:
- branch
referenceName:
- master
detail-type:
- CodeCommit Repository State Change
Targets:
- Id: codepipeline
RoleArn: !GetAtt IAMRoleForEventBridge.Arn
Arn: !Sub arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:${PipelineName}
[作業4]テンプレートの補足 SourceステージのIAMロール
CodePipeline自体に設定するサービスロールと、Sourceステージに設定するIAMロールを区別することが出来ます。
Sourceステージに作業3で作成したIAMのActionロールを設定することで、テスト環境のCodeCommitリポジトリを操作することが出来ます。
CodePipeline(Sourceステージのみ抜粋)
CodePipelineForLambda:
Type: AWS::CodePipeline::Pipeline
Properties:
###省略###
RoleArn: !ImportValue IAMRoleFoCodePipelineARN
Stages:
- Name: Source
Actions:
- Name: Commit
###省略###
RoleArn: !Ref STGCodeCommitIAMRole
Configuration:
RepositoryName: !Ref STGRepositoryName
BranchName: master
PollForSourceChanges: false
RunOrder: 1
[作業4]テンプレートのパラメータ
以上でCFnでの作業は全て完了しました。あと少しです。
[作業5]本番環境のEventBusのアクセス許可設定変更
この時点で、masterブランチへのマージ作業から本番環境のLambdaをデプロイする為の一連の流れはほぼ完成しています。
[一連の流れ]
1.テスト環境のEventBridge発動
2.★本番環境のEventBus発動
3.本番環境のEventBridge発動
4.本番環境のCodePipeline発動
5.本番環境へLambdaデプロイ
現時点では上記の★の部分が実行できません。
作業5ではテスト環境のEventBridgeが本番環境のEventBusを発動させるためのアクセス許可を設定します。
本番環境のdefaultのEventBusを開き、リソースベースのポリシーに以下を加えます。
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "AllowCodeCommitEvents",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::{テスト環境}:root"
},
"Action": "*",
"Resource": "arn:aws:events:ap-northeast-1:{本番環境}:event-bus/default"
}]
}
操作対象がdefaultのEventBusであることもポイントです。
EventBusはdefaultのもの以外に自分で作成できるものもありますが、AWSサービス間の連携には必ずdefaultのEventBusを使わなくてはなりません。
※2021年3月時点の情報です。
詳しくはEventBridgeのBlackBeltの「EventBridgeのアーキテクチャ」をご参照ください。
AWS Black Belt Online Seminar Amazon EventBridge
[作業6]本番環境へLambdaをデプロイ!
以上で準備が全て完了しました。
少し補足を入れながら、masterブランチにstgをマージして本番環境にLambdaをデプロイしてみます。
補足事項
- buildspec.ymlの構成と配置場所
- SAMテンプレート
- CodeCommitのブランチ
buildspec.ymlの構成
buildspec.ymlのsam packageコマンドでは必ずcmkを指定して成果物を暗号化した上で作成します。
template-fileのパスはbuildspec.yml自身の配置場所によって変わるので注意してください。
version: 0.2
phases:
install:
runtime-versions:
python: 3.8
build:
commands: |
sam package --template-file ./Test-Function/template.yaml --s3-bucket ${BUCKET_NAME} --kms-key-id ${CODEBUILD_KMS_KEY_ID} --output-template-file packaged-template.yaml
artifacts:
type: zip
files:
- packaged-template.yaml
“-kms-key-id ${CODEBUILD_KMS_KEY_ID}”を指定しないと、バケットポリシーによりPutObjectがはじかれます。
buildspec.ymlの配置場所
今回はbuildspec.ymlをlambdaリポジトリの直下に配置しましたが、リポジトリ内に配置されていれば必ずしも直下に置く必要はありません。
配置場所を変更する場合は、CFnのCodeBuildProjectのBuildSpecのパスとbuildspec.yml内のコマンドのパスを変えてください。
BuildSpecのパス
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
###省略###
Source:
BuildSpec: buildspec.yml #--★
Type: CODEPIPELINE
SAMテンプレート
今回はCloud9の機能を使い、Cloud9上でLambdaを新規作成しました。
よってSAMのテンプレートもデフォルトのものを使っております。Lambdaの名前だけ「Test-Function」となるよう追加しました。
デフォルトではLambda Functionの直下に配置されていましたのでこのまま利用しております。
CodeCommitのブランチ
今回の構成ではCodeCommitのブランチに少なくともmasterとstgの2つのブランチが必要です。
時流に乗ってprodブランチにしようかとも思ったのですが今回はCodeCommitのデフォルトに従いました。
それではテスト環境のCodeCommitで、stgブランチをmasterへマージしてみます。
pullリクエストの作成
マージ
マージした直後、本番環境のCodePipelineが動き始めます。
CodePipelineが正常に終了した場合、CloudFormationのスタック「lambda-pipeline-changeset」が作成されます。※スタック名はCFnテンプレートで指定可能
「REVIEW_IN_PROGRESS」というステータスで作成されますので、変更セットを実行します。
少し待ったら、Lambdaがデプロイされました。
以上です!この構成であれば、複数の本番AWSアカウントに対してまとめてデプロイすることが可能になります。
ぜひご活用ください。
-
PICK UP
ピックアップ
-
ピックアップコンテンツがありません
-
RANKING
人気の記事
-
-
1
AWS CloudFormationでBlueGr…
AWS CloudFormationでBlueGreenデプロイを実現してみた(…
2019/11/25
-
2
マルチアカウントで構成管理情報の自動収集を行う(A…
マルチアカウントで構成管理情報の自動収集を行う(AWS)
2021/06/14
-
3
Lambdaのマルチアカウントデプロイ 構築編
Lambdaのマルチアカウントデプロイ 構築編
2021/03/26
-
4
EKSを理解する(第1回)eksctl・IAM・R…
EKSを理解する(第1回)eksctl・IAM・RBAC
2020/04/09
-
5
Azure ADテナント作成/Azureサブスクリ…
Azure ADテナント作成/Azureサブスクリプション契約時に検討すべきこと
2022/02/02
-
-
ARCHIVE
アーカイブ
-
- January 2024 (1)
- December 2023 (2)
- June 2023 (2)
- May 2023 (1)
- April 2023 (1)
- March 2023 (2)
- February 2023 (2)
- January 2023 (1)
- December 2022 (2)
- October 2022 (2)
- September 2022 (2)
- August 2022 (1)



