こんにちは。SCSKのふくちーぬです。
皆さんは、イベントベースのCodePipelineのパイプラインを利用していますでしょうか。それともポーリングベースのパイプラインを利用していますでしょうか。
まだポーリングベースを利用している方は、本記事を読んでいただきイベントベースへの移行をしていただけると幸いです。(ふくちーぬもその内の1人でした。。)
本記事では、以下のAWS公式ドキュメントに従いCodeCommitをソースとしたCloudFormationで構築済みのポーリングベースのCodepipelineからイベントベースへの移行を実施します。
CodePipelineの検出オプションの種類
CodePipelineには、ソースの検出オプションとしてポーリングベース・イベントベースの2種類があります。
ポーリングベースでは、CodePipelineがCodeCommit内の対象ブランチに対して定期的に監視することで、変更を検出しています。
イベントベースでは、対象ブランチに変更があった際にEventBridgeにイベントを送信するだけです。すなわちCodePipelineは、どんと構えてEventBridgeからのメッセージを待っていればよいだけです。
ポーリングベースのパイプラインの移行を推奨している件
2023年4月下旬に、AWS サポートから以下のようなメールが届きました。
本メッセージは、1つ以上ポーリングパイプラインをお持ちのお客様にお送りしています。ポーリングパイプラインは、変更をポーリングするように設定されたソースアクションが少なくとも1つあるパイプラインとして定義されます。AWS CodePipelineチームは、2023年5月25日より、非アクティブなパイプラインでのポーリングを無効にします。非アクティブなパイプラインとは、過去30日間にパイプラインの実行が開始されていないパイプラインと定義されます。Amazon EventBridgeルール、AWS CodeStar接続、またはウェブフックのみを使用してパイプラインをトリガーする非アクティブなパイプラインは影響を受けません。また、アクティブなパイプラインも影響を受けません。
ソースのトリガーメカニズムとして、Amazon EventBridge、AWS CodeStar接続、またはウェブフックを使用するように更新することをお勧めします。
つまり、「30日以上利用されていないポーリングベースのパイプラインを無効にする」、「ポーリングベースのパイプラインを移行することを推奨する」のアナウンスをしています。
現時点でも、ポーリングベースのパイプラインを新規に作成することはできます。また無効になったパイプラインも手動で実行することで、パイプラインを起動することは可能です。
推測ですが、AWS的にCodePipelineがポーリングするコストが割りに合っていないことも要因の1つかもしれませんね。
イベントベースのパイプラインを推奨する理由
- ソースリポジトリのブランチの変更を迅速に検出できるようになり、パイプライン実行パフォーマンスが向上する
CI/CDパイプラインの準備
Cloud9の作成
以下に AWS Cloud9 の作成方法を記載しているので参考にしてください。
Cloud9とCodeCommitの連携
Cloud9からCodeCommitにプッシュできるように準備してください。
CodeCommitへのソースコード配置
今回の検証ではCodeCommitに配置するものは任意のもので問題ありませんが、以下を利用することにします。
CI/CDパイプラインの作成
ご使用のAWSアカウント内にポーリングベースのパイプラインがCloudFormationにて作成済みの方は、それをご利用ください。
今回は、新規にポーリングベースのパイプラインを作成した後に、イベントベースへ移行します。
ポーリングベースのパイプラインの作成
ポイントはパイプラインの定義にて、”PollForSourceChanges”を”true”に設定することでポーリングベースのパイプラインを作成できます。
以下のCloudFormationテンプレートをデプロイして、ポーリングベースのパイプラインを構築してください。
AWSTemplateFormatVersion: 2010-09-09 Description: cfn CI/CD Pipeline Parameters: ResourceName: Type: String REPOSITORYNAME: Type: String Description: aws codecommit repository name STACKNAME: Type: String MailAddress: Type: String Resources: ArtifactStoreBucket: Type: AWS::S3::Bucket DeletionPolicy: Retain Properties: BucketName: !Sub s3bucket-${AWS::AccountId}-artifactbucket CodeBuildBucket: Type: AWS::S3::Bucket DeletionPolicy: Retain Properties: BucketName: !Sub s3bucket-${AWS::AccountId}-codebuildtbucket # ------------------------------------------------------------# # CodeBuild Role (IAM) # ------------------------------------------------------------# CodeBuildRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: codebuild.amazonaws.com Path: / ManagedPolicyArns: - !Ref CodeBuildPolicy - arn:aws:iam::aws:policy/AWSCloudFormationFullAccess RoleName: !Sub "IRL-CODEBUILD-S3CloudWatchlogsAccess" # ------------------------------------------------------------# # CodeBuild Role Policy (IAM) # ------------------------------------------------------------# CodeBuildPolicy: Type: AWS::IAM::ManagedPolicy Properties: ManagedPolicyName: CodeBuildAccess PolicyDocument: Version: '2012-10-17' Statement: - Sid: CloudWatchLogsAccess Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: - !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/* - Sid: S3Access Effect: Allow Action: - s3:PutObject - s3:GetObject - s3:GetObjectVersion Resource: - !Sub arn:aws:s3:::${ArtifactStoreBucket} - !Sub arn:aws:s3:::${ArtifactStoreBucket}/* - !Sub arn:aws:s3:::${CodeBuildBucket} - !Sub arn:aws:s3:::${CodeBuildBucket}/* - Sid: IAMPass Effect: Allow Action: - iam:PassRole Resource: "*" - Sid: CloudFormationAccess Effect: Allow Action: cloudformation:ValidateTemplate Resource: "*" # ------------------------------------------------------------# # CodeBuild linter Project # ------------------------------------------------------------# CodeBuildProjectLint: Type: AWS::CodeBuild::Project Properties: Name: !Sub ${ResourceName}-project-lint ServiceRole: !GetAtt CodeBuildRole.Arn Artifacts: Type: CODEPIPELINE Environment: Type: LINUX_CONTAINER ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0 EnvironmentVariables: - Name: AWS_REGION Value: !Ref AWS::Region - Name: S3_BUCKET Value: !Ref CodeBuildBucket Source: Type: CODEPIPELINE # ------------------------------------------------------------# # CodeBuild changeset Project # ------------------------------------------------------------# CodeBuildProjectChangeset: Type: AWS::CodeBuild::Project Properties: Name: !Sub ${ResourceName}-project-changeset ServiceRole: !GetAtt CodeBuildRole.Arn Artifacts: Type: CODEPIPELINE Environment: Type: LINUX_CONTAINER ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0 EnvironmentVariables: - Name: AWS_REGION Value: !Ref AWS::Region - Name: S3_BUCKET Value: !Ref CodeBuildBucket - Name: STACK_NAME Value: !Ref STACKNAME - Name: CFNROLE_ARN Value: !GetAtt CloudformationRole.Arn Source: Type: CODEPIPELINE BuildSpec: changeset-buildspec.yaml # ------------------------------------------------------------# # CloudFormation Role (IAM) # ------------------------------------------------------------# CloudformationRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: sts:AssumeRole Principal: Service: cloudformation.amazonaws.com Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AdministratorAccess RoleName: "IRL-CLOUDFORMATION-ServiceFullAccess" # ------------------------------------------------------------# # CodePipeline Role (IAM) # ------------------------------------------------------------# PipelineRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: codepipeline.amazonaws.com Path: / ManagedPolicyArns: - !Ref PipelinePolicy RoleName: "IRL-CODEPIPELINE-Access" # ------------------------------------------------------------# # CodePipeline Role Policy (IAM) # ------------------------------------------------------------# PipelinePolicy: Type: AWS::IAM::ManagedPolicy Properties: ManagedPolicyName: CodePipelineAccess PolicyDocument: Version: '2012-10-17' Statement: - Sid: S3FullAccess Effect: Allow Action: s3:* Resource: - !Sub arn:aws:s3:::${ArtifactStoreBucket} - !Sub arn:aws:s3:::${ArtifactStoreBucket}/* - Sid: FullAccess Effect: Allow Action: - cloudformation:* - iam:PassRole - codecommit:GetRepository - codecommit:ListBranches - codecommit:GetUploadArchiveStatus - codecommit:UploadArchive - codecommit:CancelUploadArchive - codecommit:GetBranch - codecommit:GetCommit Resource: "*" - Sid: CodeBuildAccess Effect: Allow Action: - codebuild:BatchGetBuilds - codebuild:StartBuild Resource: !GetAtt CodeBuildProjectLint.Arn - Sid: CodeBuildChangesetAccess Effect: Allow Action: - codebuild:BatchGetBuilds - codebuild:StartBuild Resource: !GetAtt CodeBuildProjectChangeset.Arn - Sid: SNSAccess Effect: Allow Action: - sns:Publish Resource: !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${ResourceName}-topic # ------------------------------------------------------------# # CodePipeline # ------------------------------------------------------------# Pipeline: Type: AWS::CodePipeline::Pipeline Properties: Name: !Sub ${ResourceName}-pipeline RoleArn: !GetAtt PipelineRole.Arn ArtifactStore: Type: S3 Location: !Ref ArtifactStoreBucket Stages: - Name: Source Actions: - Name: download-source ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: CodeCommit Configuration: RepositoryName: !Ref REPOSITORYNAME BranchName: main PollForSourceChanges: true #ポーリングベースのパイプラインでは、"true"に設定 OutputArtifacts: - Name: SourceOutput - Name: Test Actions: - InputArtifacts: - Name: SourceOutput Name: testing ActionTypeId: Category: Test Owner: AWS Version: 1 Provider: CodeBuild Configuration: ProjectName: !Ref CodeBuildProjectLint - Name: Build Actions: - InputArtifacts: - Name: SourceOutput Name: changeset ActionTypeId: Category: Build Owner: AWS Version: 1 Provider: CodeBuild OutputArtifacts: - Name: BuildOutput Configuration: ProjectName: !Ref CodeBuildProjectChangeset Namespace: BuildVariables - Name: Approval Actions: - Name: approve-changeset ActionTypeId: Category: Approval Owner: AWS Version: 1 Provider: Manual Configuration: ExternalEntityLink: !Sub https://${AWS::Region}.console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/changesets/changes?stackId=#{BuildVariables.SackId}&changeSetId=#{BuildVariables.ChangeSetId} NotificationArn: !GetAtt SNSTopic.TopicArn - Name: Deploy Actions: - Name: execute-changeset ActionTypeId: Category: Deploy Owner: AWS Version: 1 Provider: CloudFormation Configuration: StackName: !Join [ '-', [ !Ref ResourceName, 'infra-stack' ] ] ActionMode: CHANGE_SET_EXECUTE ChangeSetName: changeset RoleArn: !GetAtt CloudformationRole.Arn # ------------------------------------------------------------# # SNS # ------------------------------------------------------------# SNSTopic: Type: AWS::SNS::Topic Properties: Subscription: - Endpoint: !Ref MailAddress Protocol: email TopicName: !Sub ${ResourceName}-topic
ポーリングベースのパイプラインの一覧の取得
今回はboto3(Python)を使用して、ポーリングベースのパイプラインの一覧を取得してみます。
Cloud9へのboto3のインストール
以下のコマンドを実行して、boto3ライブラリのインストールをします。
pip install boto3
以下のコマンドを実行して、バージョンが返却されればインストール済みとなります。今回は、”boto3 1.33.11″が返ってきています。
pip list | grep boto3
Pythonスクリプトの作成
Cloud9におけるGUI経由でのファイル作成方法は、以下を参照ください。
以下のPythonファイルを任意のディレクトリに作成してください。ファイル名は、”PollingPipelinesExtractor.py”とします。
import boto3 import sys import time import math hasNextToken = True nextToken = "" pollablePipelines = [] lastExecutedTimes = [] if len(sys.argv) == 1: raise Exception("Please provide region name.") session = boto3.Session(profile_name='default', region_name=sys.argv[1]) codepipeline = session.client('codepipeline') def is_pollable_action(action): actionTypeId = action['actionTypeId'] configuration = action['configuration'] return actionTypeId['owner'] in {"AWS", "ThirdParty"} and actionTypeId['provider'] in {"GitHub", "CodeCommit", "S3"} and ('PollForSourceChanges' not in configuration or configuration['PollForSourceChanges'] == 'true') def has_pollable_actions(pipeline): hasPollableAction = False pipelineDefinition = codepipeline.get_pipeline(name=pipeline['name'])['pipeline'] for action in pipelineDefinition['stages'][0]['actions']: hasPollableAction = is_pollable_action(action) if hasPollableAction: break return hasPollableAction def get_last_executed_time(pipelineName): pipelineExecutions=codepipeline.list_pipeline_executions(pipelineName=pipelineName)['pipelineExecutionSummaries'] if pipelineExecutions: return pipelineExecutions[0]['startTime'].strftime("%A %m/%d/%Y, %H:%M:%S") else: return "Not executed in last year" while hasNextToken: if nextToken=="": list_pipelines_response = codepipeline.list_pipelines() else: list_pipelines_response = codepipeline.list_pipelines(nextToken=nextToken) if 'nextToken' in list_pipelines_response: nextToken = list_pipelines_response['nextToken'] else: hasNextToken= False for pipeline in list_pipelines_response['pipelines']: if has_pollable_actions(pipeline): pollablePipelines.append(pipeline['name']) lastExecutedTimes.append(get_last_executed_time(pipeline['name'])) fileName="{region}-{timeNow}.csv".format(region=sys.argv[1],timeNow=math.trunc(time.time())) file = open(fileName, 'w') print ("{:<30} {:<30} {:<30}".format('Polling Pipeline Name', '|','Last Executed Time')) print ("{:<30} {:<30} {:<30}".format('_____________________', '|','__________________')) for i in range(len(pollablePipelines)): print("{:<30} {:<30} {:<30}".format(pollablePipelines[i], '|', lastExecutedTimes[i])) file.write("{pipeline},".format(pipeline=pollablePipelines[i])) file.close() print("\nSaving Polling Pipeline Names to file {fileName}".format(fileName=fileName))
Pythonスクリプトの実行
以下のコマンドを実行して、pythonスクリプトを実行します。
引数として、指定のリージョンを入力します。ここでは、東京リージョンの”ap-northeast-1″を指定します。
python3 PollingPipelinesExtractor.py ap-northeast-1
指定のリージョン内に存在しているポーリングベースのパイプラインの一覧を取得することができます。これで、どのパイプラインがポーリングベースを採用しているのか一目瞭然ですね。またCSVファイルとしても出力されています。
今回は、”cicd-20231210-pipeline”を新規作成したので表示されています。ご自身で作成したものと読み替えてください。
イベントベースのパイプラインへ移行
ポーリングベースからイベントベースへ移行するために、CloudFormationテンプレートの修正をしていきます。
PollForSourceChangesの変更
以下のように、ポーリングベースを採用しないようにCodePipelineの”PollForSourceChanges”プロパティを”false”に変更します。
Stages: - Name: Source Actions: - Name: download-source ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: CodeCommit Configuration: RepositoryName: !Ref REPOSITORYNAME BranchName: main PollForSourceChanges: false #イベントベースを採用するためfalseに変更 OutputArtifacts: - Name: SourceOutput
EventBridgeが利用するIAMポリシー・ロールの追加
以下のように、EventBridgeが利用するためのIAMポリシー・ロールを作成するための記述を追加します。
EventBridgeがCodePipelineを起動できる権限を付与しています。
# ------------------------------------------------------------# # CodePipeline Events Role (IAM) # ------------------------------------------------------------# PipelineEventsRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: events.amazonaws.com Path: / ManagedPolicyArns: - !Ref PipelineEventsPolicy RoleName: !Sub "IRL-EVENTBRIDGE-CodePipelineAccess" # ------------------------------------------------------------# # CodePipeline Events Role Policy (IAM) # ------------------------------------------------------------# PipelineEventsPolicy: Type: AWS::IAM::ManagedPolicy Properties: ManagedPolicyName: CodePipelineAccessForEvents PolicyDocument: Statement: - Action: codepipeline:StartPipelineExecution Effect: Allow Resource: - !Sub arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:${Pipeline} Version: "2012-10-17"
EventBridgeの追加
以下のように、EventBridge本体の記述を追加します。対象のリポジトリや付与するロール等の指定もしています。
これによりCodeCommitのブランチの更新をトリガーにCodePipelineを起動できるようになります。
# ------------------------------------------------------------# # EventBridge Rule for Starting CodePipeline # ------------------------------------------------------------# PipelineEventsRule: Type: AWS::Events::Rule Properties: Name: !Sub ${ResourceName}-rule-pipeline EventBusName: !Sub "arn:aws:events:${AWS::Region}:${AWS::AccountId}:event-bus/default" EventPattern: source: - aws.codecommit resources: - !Sub arn:aws:codecommit:${AWS::Region}:${AWS::AccountId}:${REPOSITORYNAME} detail-type: - "CodeCommit Repository State Change" detail: event: - referenceCreated - referenceUpdated referenceName: - main State: ENABLED Targets: - Arn: Fn::Join: - "" - - "arn:" - Ref: AWS::Partition - ":codepipeline:" - Ref: AWS::Region - ":" - Ref: AWS::AccountId - ":" - Ref: Pipeline Id: Target RoleArn: !GetAtt PipelineEventsRole.Arn
完成したテンプレート
完成したテンプレートは、以下の通りです。
AWSTemplateFormatVersion: 2010-09-09 Description: cfn CI/CD Pipeline Parameters: ResourceName: Type: String REPOSITORYNAME: Type: String Description: aws codecommit repository name STACKNAME: Type: String MailAddress: Type: String Resources: ArtifactStoreBucket: Type: AWS::S3::Bucket DeletionPolicy: Retain Properties: BucketName: !Sub s3bucket-${AWS::AccountId}-artifactbucket CodeBuildBucket: Type: AWS::S3::Bucket DeletionPolicy: Retain Properties: BucketName: !Sub s3bucket-${AWS::AccountId}-codebuildtbucket # ------------------------------------------------------------# # EventBridge Rule for Starting CodePipeline # ------------------------------------------------------------# PipelineEventsRule: Type: AWS::Events::Rule Properties: Name: !Sub ${ResourceName}-rule-pipeline EventBusName: !Sub "arn:aws:events:${AWS::Region}:${AWS::AccountId}:event-bus/default" EventPattern: source: - aws.codecommit resources: - !Sub arn:aws:codecommit:${AWS::Region}:${AWS::AccountId}:${REPOSITORYNAME} detail-type: - "CodeCommit Repository State Change" detail: event: - referenceCreated - referenceUpdated referenceName: - main State: ENABLED Targets: - Arn: Fn::Join: - "" - - "arn:" - Ref: AWS::Partition - ":codepipeline:" - Ref: AWS::Region - ":" - Ref: AWS::AccountId - ":" - Ref: Pipeline Id: Target RoleArn: !GetAtt PipelineEventsRole.Arn # ------------------------------------------------------------# # CodePipeline Events Role (IAM) # ------------------------------------------------------------# PipelineEventsRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: events.amazonaws.com Path: / ManagedPolicyArns: - !Ref PipelineEventsPolicy RoleName: !Sub "IRL-EVENTBRIDGE-CodePipelineAccess" # ------------------------------------------------------------# # CodePipeline Events Role Policy (IAM) # ------------------------------------------------------------# PipelineEventsPolicy: Type: AWS::IAM::ManagedPolicy Properties: ManagedPolicyName: CodePipelineAccessForEvents PolicyDocument: Statement: - Action: codepipeline:StartPipelineExecution Effect: Allow Resource: - !Sub arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:${Pipeline} Version: "2012-10-17" # ------------------------------------------------------------# # CodeBuild Role (IAM) # ------------------------------------------------------------# CodeBuildRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: codebuild.amazonaws.com Path: / ManagedPolicyArns: - !Ref CodeBuildPolicy - arn:aws:iam::aws:policy/AWSCloudFormationFullAccess RoleName: !Sub "IRL-CODEBUILD-S3CloudWatchlogsAccess" # ------------------------------------------------------------# # CodeBuild Role Policy (IAM) # ------------------------------------------------------------# CodeBuildPolicy: Type: AWS::IAM::ManagedPolicy Properties: ManagedPolicyName: CodeBuildAccess PolicyDocument: Version: '2012-10-17' Statement: - Sid: CloudWatchLogsAccess Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: - !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/* - Sid: S3Access Effect: Allow Action: - s3:PutObject - s3:GetObject - s3:GetObjectVersion Resource: - !Sub arn:aws:s3:::${ArtifactStoreBucket} - !Sub arn:aws:s3:::${ArtifactStoreBucket}/* - !Sub arn:aws:s3:::${CodeBuildBucket} - !Sub arn:aws:s3:::${CodeBuildBucket}/* - Sid: IAMPass Effect: Allow Action: - iam:PassRole Resource: "*" - Sid: CloudFormationAccess Effect: Allow Action: cloudformation:ValidateTemplate Resource: "*" # ------------------------------------------------------------# # CodeBuild linter Project # ------------------------------------------------------------# CodeBuildProjectLint: Type: AWS::CodeBuild::Project Properties: Name: !Sub ${ResourceName}-project-lint ServiceRole: !GetAtt CodeBuildRole.Arn Artifacts: Type: CODEPIPELINE Environment: Type: LINUX_CONTAINER ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0 EnvironmentVariables: - Name: AWS_REGION Value: !Ref AWS::Region - Name: S3_BUCKET Value: !Ref CodeBuildBucket Source: Type: CODEPIPELINE # ------------------------------------------------------------# # CodeBuild changeset Project # ------------------------------------------------------------# CodeBuildProjectChangeset: Type: AWS::CodeBuild::Project Properties: Name: !Sub ${ResourceName}-project-changeset ServiceRole: !GetAtt CodeBuildRole.Arn Artifacts: Type: CODEPIPELINE Environment: Type: LINUX_CONTAINER ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0 EnvironmentVariables: - Name: AWS_REGION Value: !Ref AWS::Region - Name: S3_BUCKET Value: !Ref CodeBuildBucket - Name: STACK_NAME Value: !Ref STACKNAME - Name: CFNROLE_ARN Value: !GetAtt CloudformationRole.Arn Source: Type: CODEPIPELINE BuildSpec: changeset-buildspec.yaml # ------------------------------------------------------------# # CloudFormation Role (IAM) # ------------------------------------------------------------# CloudformationRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: sts:AssumeRole Principal: Service: cloudformation.amazonaws.com Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AdministratorAccess RoleName: "IRL-CLOUDFORMATION-ServiceFullAccess" # ------------------------------------------------------------# # CodePipeline Role (IAM) # ------------------------------------------------------------# PipelineRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: codepipeline.amazonaws.com Path: / ManagedPolicyArns: - !Ref PipelinePolicy RoleName: "IRL-CODEPIPELINE-Access" # ------------------------------------------------------------# # CodePipeline Role Policy (IAM) # ------------------------------------------------------------# PipelinePolicy: Type: AWS::IAM::ManagedPolicy Properties: ManagedPolicyName: CodePipelineAccess PolicyDocument: Version: '2012-10-17' Statement: - Sid: S3FullAccess Effect: Allow Action: s3:* Resource: - !Sub arn:aws:s3:::${ArtifactStoreBucket} - !Sub arn:aws:s3:::${ArtifactStoreBucket}/* - Sid: FullAccess Effect: Allow Action: - cloudformation:* - iam:PassRole - codecommit:GetRepository - codecommit:ListBranches - codecommit:GetUploadArchiveStatus - codecommit:UploadArchive - codecommit:CancelUploadArchive - codecommit:GetBranch - codecommit:GetCommit Resource: "*" - Sid: CodeBuildAccess Effect: Allow Action: - codebuild:BatchGetBuilds - codebuild:StartBuild Resource: !GetAtt CodeBuildProjectLint.Arn - Sid: CodeBuildChangesetAccess Effect: Allow Action: - codebuild:BatchGetBuilds - codebuild:StartBuild Resource: !GetAtt CodeBuildProjectChangeset.Arn - Sid: SNSAccess Effect: Allow Action: - sns:Publish Resource: !Sub arn:aws:sns:${AWS::Region}:${AWS::AccountId}:${ResourceName}-topic # ------------------------------------------------------------# # CodePipeline # ------------------------------------------------------------# Pipeline: Type: AWS::CodePipeline::Pipeline Properties: Name: !Sub ${ResourceName}-pipeline RoleArn: !GetAtt PipelineRole.Arn ArtifactStore: Type: S3 Location: !Ref ArtifactStoreBucket Stages: - Name: Source Actions: - Name: download-source ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: CodeCommit Configuration: RepositoryName: !Ref REPOSITORYNAME BranchName: main PollForSourceChanges: false #イベントベースを採用するためfalseに変更 OutputArtifacts: - Name: SourceOutput - Name: Test Actions: - InputArtifacts: - Name: SourceOutput Name: testing ActionTypeId: Category: Test Owner: AWS Version: 1 Provider: CodeBuild Configuration: ProjectName: !Ref CodeBuildProjectLint - Name: Build Actions: - InputArtifacts: - Name: SourceOutput Name: changeset ActionTypeId: Category: Build Owner: AWS Version: 1 Provider: CodeBuild OutputArtifacts: - Name: BuildOutput Configuration: ProjectName: !Ref CodeBuildProjectChangeset Namespace: BuildVariables - Name: Approval Actions: - Name: approve-changeset ActionTypeId: Category: Approval Owner: AWS Version: 1 Provider: Manual Configuration: ExternalEntityLink: !Sub https://${AWS::Region}.console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/changesets/changes?stackId=#{BuildVariables.SackId}&changeSetId=#{BuildVariables.ChangeSetId} NotificationArn: !GetAtt SNSTopic.TopicArn - Name: Deploy Actions: - Name: execute-changeset ActionTypeId: Category: Deploy Owner: AWS Version: 1 Provider: CloudFormation Configuration: StackName: !Join [ '-', [ !Ref ResourceName, 'infra-stack' ] ] ActionMode: CHANGE_SET_EXECUTE ChangeSetName: changeset RoleArn: !GetAtt CloudformationRole.Arn # ------------------------------------------------------------# # SNS # ------------------------------------------------------------# SNSTopic: Type: AWS::SNS::Topic Properties: Subscription: - Endpoint: !Ref MailAddress Protocol: email TopicName: !Sub ${ResourceName}-topic
CI/CDパイプラインの更新
上記テンプレートを使用して、CI/CDパイプラインのスタックを更新します。
CloudFormationコンソールから該当のスタック選択して、”更新”を押下してください。
修正済みのテンプレートファイルをアップデートして、”次へ”を押下してください。
既存のパラメータ等は変更することなく、”次へ”を押下してください。
“次へ”を押下してください。
最後にレビュー画面に遷移します。内容に間違いがないか確認します。
変更セットのレビューにて、IAMポリシー・IAMロール・EventBridgeルールが追加されることを確認します。またCodePipelineでは、変更があることも確認します。問題なければ”送信”を押下してください。
数分経過すると、スタックの更新が完了します。
移行の確認
移行が完了したかどうか、こちらの手順で再度スクリプトを実行することで確かめます。
先ほどまで存在した”cicd-20231210-pipeline”が表示されていないため、イベントベースのパイプラインとして正常に認識されています。
これにて移行完了となります。お疲れ様でした。
パイプライン起動確認
念の為、イベントベースのパイプラインが起動するか確認しておきます。
CodeCommitにプッシュすると、パイプラインが起動していることが分かります。(承認ステージを組み込んでいるため、レビュー中で一時停止しています。)
また、イベントベースへの移行を勧める警告メッセージも表示されなくなっています。
ちなみに、ポーリングベースのパイプラインを利用していると、CodePipelineの対象パイプラインの画面を開くたびに以下のように警告メッセージが表示されます。
パイプラインがアクティブの場合:
このパイプラインには、ポーリング用に設定されたソース(download-source)があります。変更検出用に推奨されるイベントベースのメカニズムにパイプラインを移行(更新)します。詳細については、「移行ガイド」を参照してください。
30日以上パイプラインを起動していない(アクティブでない)場合:
○か月前時点で、CodePipelineはこのパイプラインのポーリングを無効にしています。これは、以前30日間に実行されていないためです。推奨されるイベントベースのメカニズムを使用して、新しいパイプライン実行を開始します。
最後に
いかがでしたでしょうか。
CodeCommitをソースとしたCloudFormationで構築済みのポーリングベースのCodePipelineをイベントベースへと移行しました。
既存のCodePipelineでポーリングベースを利用している方は、是非この手順に沿って移行の検討をしていただければと思います。また新規でパイプラインを構築する際は、イベントベースでパイプラインを構築するように意識してください。
本記事が皆様のお役にたてば幸いです。
ではサウナラ~🔥