どうも、AWS勉強中のとがみんです。
以前の記事で、AWSのコンソールから、Serverless FrameworkのCICDの構築をCodePipelineで実装してきました。
この記事では、ServerlessFrameworkのCICDの構築をCloudFormationを用いてコード管理できるように、そのコードの作成とCloudFormationによるCodePipelineの構築・動作確認していこうと思います。
インフラ構築をコードで管理できると、環境の再構築を自動化することができ、工数削減や人為的なミスが発生する確率が減らせるため、CloudFormationでインフラ構築を自動化します。
Contents
今回作成するもの
Serverless Frameworkを活用したサービスの構築・更新をCodeCommitのdevelopブランチへの変更を検知して実行するCodePipelineを作成します。
AWSのコンソールから作成するのではなく、CloudFormationを活用して構築します。
まずは、CodeBuildとCodePipelineを構築するCloudFormationのテンプレートを作成し、CloudFormationのスタックを作成します。それにより、CodeBuildとCodePipelineを構築します。
その後、その構築されたCICDが問題なく動作するかを確認します。
CodeCommitの対象ブランチに変更を加え、簡易サンプルアプリケーションが構築されるかを確認します。
作業手順概要
今回はCloudFormationのテンプレートを作成し、パイプラインの構築を行い、Serverless Frameworkを活用したアプリケーションで動作を確認していきます。
- CICD構築のためのCloudFormationテンプレートの作成
- CloudFormationでCodePipelineの構築
- developブランチへの変更をトリガーにCodePipelineの動作確認
作業詳細
CICD構築のためのCloudFormationテンプレートの作成
下記のようなテンプレートを作成しました。ブロックごとに詳細をまとめていきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | AWSTemplateFormatVersion: 2010-09-09 Description: Serverless Framework deploy pipeline test Parameters: RepositoryName: Type: String Default: serverless-deploy-example BranchName: Type: String Default: develop Resources: #CodePipelineで使用するS3 ArtifactsBucket: Type: AWS::S3::Bucket Properties: BucketName: !Sub ${RepositoryName}-artifacts #CodeBuild CodeBuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Sub ${RepositoryName} Artifacts: Type: CODEPIPELINE Source: Type: CODEPIPELINE Environment: ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/standard:3.0 PrivilegedMode: false Type: LINUX_CONTAINER ServiceRole: !GetAtt CodeBuildServiceRole.Arn #CodeBuildのIAMロール CodeBuildServiceRole: Type: AWS::IAM::Role Properties: RoleName: !Sub CodeBuild-${RepositoryName}-Role Policies: - PolicyName: !Sub CodeBuild-${RepositoryName}-Policy PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - "*" Resource: - "*" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: Effect: Allow Principal: Service: codebuild.amazonaws.com Action: sts:AssumeRole #CodePipeline CodePipelineProject: Type: AWS::CodePipeline::Pipeline Properties: Name: !Sub ${RepositoryName} RoleArn: !GetAtt CodePipelineServiceRole.Arn Stages: - Name: Source Actions: - Name: SourceAction ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: CodeCommit OutputArtifacts: - Name: SourceArtifact Configuration: RepositoryName: !Sub ${RepositoryName} BranchName: !Sub ${BranchName} RunOrder: 1 - Name: Build Actions: - Name: BuildAction InputArtifacts: - Name: SourceArtifact OutputArtifacts: - Name: BuildArtifact ActionTypeId: Category: Build Owner: AWS Version: 1 Provider: CodeBuild Configuration: ProjectName: !Ref CodeBuildProject RunOrder: 2 ArtifactStore: Type: S3 Location: !Ref ArtifactsBucket #CodePipelineのIAMロール CodePipelineServiceRole: Type: AWS::IAM::Role Properties: RoleName: !Sub CodePipeline-${RepositoryName}-Role Policies: - PolicyName: !Sub CodePipeline-${RepositoryName}-Role PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - "*" Resource: - "*" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: Effect: Allow Principal: Service: codepipeline.amazonaws.com Action: sts:AssumeRole |
Parameters
1 2 3 4 5 6 7 | Parameters: RepositoryName: Type: String Default: serverless-deploy-example BranchName: Type: String Default: develop |
Parametersでは、CodePipelineをCloudFormationで構築するときに、入力するパラメータを指定できるようにします。
今回はRepositoryNameと、BranchNameがCloudFormationのスタック作成時に入力を求められるようになります。
「指定したリポジトリ」の「指定したブランチ」に更新があった場合にそれを検知してCodePipelineが実行されるようにしていきます。
S3
1 2 3 4 | ArtifactsBucket: Type: AWS::S3::Bucket Properties: BucketName: !Sub ${RepositoryName}-artifacts |
CodePipelineの各ステージの入力&出力を格納するS3バケットを作成するコードです。
CodePipelineの出力結果を格納するために利用されるS3バケットを作成します。
CodeBuild
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | CodeBuildProject: Type: AWS::CodeBuild::Project Properties: Name: !Sub ${RepositoryName} Artifacts: Type: CODEPIPELINE Source: Type: CODEPIPELINE Environment: ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/standard:3.0 PrivilegedMode: false Type: LINUX_CONTAINER ServiceRole: !GetAtt CodeBuildServiceRole.Arn |
CodePipelineのビルドステージで指定するビルドプロジェクトを作成するコードです。
Artifacts
Artifactsプロパティは、ビルドによって生成した成果物(アーティファクト)をどう扱うかを指定するためのものです。
TypeにCODEPIPELINEと指定した場合は、その項目はCCodePipelineに指定されたものが参照され、CodePiplelineの設定の方で管理します。
AWS::CodeBuild::Project Artifacts
Source
ソースではビルド対象のソースを指定しますが、CodePipelienがその項目を管理するためTypeにCODEPIPELINEと記載しています。
Environment
Environmentoには、ビルドを実行する環境の設定をしています。
ServiceRole
CodeBuildに付与するロールを指定します。
次に定義するCodeBuildServiceRoleを指定します。
CodeBuildのIAMロール
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | CodeBuildServiceRole: Type: AWS::IAM::Role Properties: RoleName: !Sub CodeBuild-${RepositoryName}-Role Policies: - PolicyName: !Sub CodeBuild-${RepositoryName}-Policy PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - "*" Resource: - "*" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: Effect: Allow Principal: Service: codebuild.amazonaws.com Action: sts:AssumeRole |
権限に関しては、今回は、すべてのリソースに対してすべてのアクションを許可する強めのポリシーをアタッチするように記載しています。
本来であれば、必要最小限の権限で設定する方が安全ですが、簡単のために、強目の権限を設定しています。
CodePipeline
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | CodePipelineProject: Type: AWS::CodePipeline::Pipeline Properties: Name: !Sub ${RepositoryName} RoleArn: !GetAtt CodePipelineServiceRole.Arn Stages: - Name: Source Actions: - Name: SourceAction ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: CodeCommit OutputArtifacts: - Name: SourceArtifact Configuration: RepositoryName: !Sub ${RepositoryName} BranchName: !Sub ${BranchName} RunOrder: 1 - Name: Build Actions: - Name: BuildAction InputArtifacts: - Name: SourceArtifact OutputArtifacts: - Name: BuildArtifact ActionTypeId: Category: Build Owner: AWS Version: 1 Provider: CodeBuild Configuration: ProjectName: !Ref CodeBuildProject RunOrder: 2 ArtifactStore: Type: S3 Location: !Ref ArtifactsBucket |
Propertiesで指定したリポジトリ&ブランチから対象コードを取得するように設定しています。
runOrderには、ソースステージが1、ビルドステージに2と指定しています。ソースステージが実行された後にビルドステージが実行されるような設定になっています。
各ステージの入出力ファイルを格納するS3は、最初に定義したS3を指定しています。
CodePipelineのIAMロール
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | CodePipelineServiceRole: Type: AWS::IAM::Role Properties: RoleName: !Sub CodePipeline-${RepositoryName}-Role Policies: - PolicyName: !Sub CodePipeline-${RepositoryName}-Role PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - "*" Resource: - "*" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: Effect: Allow Principal: Service: codepipeline.amazonaws.com Action: sts:AssumeRole |
Codebuildに付与した権限と同様に、今回は、すべてのリソースに対してすべてのアクションを許可する強めのポリシーをアタッチするように記載しています。
本来であれば、必要最小限の権限で設定する方が安全ですが、簡単のために、強目の権限を設定しています。
CloudFormationでCodePipelineの構築
作成したCloudFormationのテンプレートを用いて、パイプラインを作成します。
スタック名にcicd-cloudformation-testと入力しました。
今回はserverless-cicd-testリポジトリのdevelopブランチをへの変更を検知してデプロイするパイプラインを構築するため、ブランチ名にはdevelop、リポジトリ名にはserverless-cicd-testを入力しました。
スタックオプションも今回は特に指定せ次に進み、スタックの作成を選択すると、CloudFormatinテンプレートに記載したリソースの作成が始まります。
成功すると、CodeBuild、CodePipeline等のリソースが作成されます。
severlessアプリケーションのdevelopブランチへの変更をトリガーにCodePipelineの動作確認
動作を試すサンプルは下記の記事をベースに作成したものになります。
serverless-cicd-testのdevelopブランチに変更をpushします。
handler.jsのmessageの項目を下記のように変更し、develpブランチにpushしました。
pushするとCodePipelineが動作したことが、CodePipelineのコンソールから確認することができます。
CodeBuildのログに出力されるエンドポイントにアクセスすると、下記のようなレスポンスが帰ってきます。
CodePiplenが動作し、変更が反映されたことが確認できました。
まとめ
CloudFormationを活用して、ServerlessFrameworkを活用したアプリケーションのCICDを構築し、その動作を確認しました。
参考
serverless frameworkをCodePipelineでデプロイするCloudFormationを作成する
フロントエンド環境をS3にデプロイするCodePipelineをCloudFormationで作成する
AWS CDK スタックデプロイ時に「’null’ values are not allowed in templates」エラーが発生したので対処した話