CodePipelineでCodeCommitにpushしたCloudFormationテンプレートからスタックの作成と更新を自動化するCICDパイプラインを構築してみた!

AWS

はじめに

今回は、CloudFormationスタックの作成をGUIやCLIで実施せず、CodeCommitにコードをpushすることを起点に行うCodePipelineを用いた仕組みを構築してみます。

この仕組みの利点は、まさにCICDのように、コードの更新とそのデプロイメントを自動化して、手動作業を減らし、効率化と作業ミスを防ぐことです。

そして、そのデプロイ対象は、EC2上のアプリケーションやS3上の静的webサイトではなく、CloudFormationスタックとしています。

つまり、YAMLテンプレートの記述次第で、AWS上のあらゆるリソースの作成を自動化できます。(GUIでポチポチしなくていい!!スタックの更新も自動!歓喜!)

以下を参考に構築していきます。

AWS::CodePipeline::Pipeline - AWS CloudFormation
Use the AWS CloudFormation AWS::CodePipeline::Pipeline resource for CodePipeline.
チュートリアル: テストおよび本稼働スタック用のパイプラインを構築する - AWS CloudFormation
継続的な配信ワークフローに使用する多数の AWS CloudFormation アクションを自動化する CodePipeline パイプラインを構築する方法を説明します。

構成図

今回の構成は非常にシンプルです。
構築対象は、S3バケットのみです。主テーマはCodeシリーズを用いたCICDの仕組みですので、構築対象は簡易的にします。

CloudFormationでCodeCommitリポジトリとCodeDeployを作成したら、あとはyamlテンプレートをCodeCommitリポジトリにpushすることで、スタックの作成と更新が自動的に行われます。

事前準備

必要なリソースを準備しておきます。

YAMLファイルを作成しておく

今回、CodeCommitのリポジトリに保管するソースコードは、以下の通り、S3バケットをデフォルト設定で作成するシンプルなYAMLテンプレートです。
任意のエディタで以下を記述したYAMLファイルを作成しておきます。

Resources:
  tests3bucket:
    Type: AWS::S3::bucket
    Properties:
      BucketName: test-s3-bucket

アーティファクト保管用S3バケットを作成しておく

アーティファクト保管用のS3バケットを作成しておきます。

設定はデフォルトで問題ないです。

今回は、my-pipeline-bucket-nameとしていますので、特に理由がなければこの名前にしておきましょう。

もし任意の名前を入力された際は、後述のCloudFormationスタック作成時のパラメータ入力時に”ArtifactsStore”の値を入力した任意の名前に変更してください。

  • アーティファクト:コードやアプリケーションのビルド成果物や展開可能なファイルなど、プロジェクトの途中経過や最終成果物ファイル。このファイルを正しく渡せていないとPipelineが失敗する。

CloudFormationで構築

CloudFormationテンプレートは以下にございます。
ダウンロードしてデスクトップなど任意のフォルダに保存します。
※その他のファイルも後述の手順で使用するためダウンロードしておきます

GitHub - kosments/cicd-pipeline-for-cfn-stack
Contribute to kosments/cicd-pipeline-for-cfn-stack development by creating an account on GitHub.

CloudFormation:YAMLテンプレートのポイント

YAMLテンプレートのポイントを記述します。

  • MyCodeCommitRepository:
    • コードをpushする先になるCodeCommitリポジトリを作成しています。
    • 細かい設定はなく、単純にリポジトリを作成しているだけです。
  • MyPipeline:
    • 今回の主テーマであるパイプラインの構築箇所です。
    • RoleArn: !GetAtt PipelineRole.arn
      • パイプライン自体に付与するIAMロールを指定しています。コード全体の後半に定義しているロールを受け取ります。ポイントは、パイプラインに何を実行させたいかによってロールに含ませるポリシーを変えることです。
        • 今回は、CloudFormationスタックの作成と更新をさせたいため、そのようにポリシーを記述しています。
    • ArtifactStore:
      • アーティファクトファイルを保管、参照するS3バケットを指定しています。
    • Stages:
      • ステージ項目では、コードがpushされてからデプロイされるまでの流れと処理内容を、パイプラインにおけるステージという単位に分けて記述します。
      • Name: Source
        • ソースステージでは、ソースコードをどこから参照するか選択できます。S3バケット、GitHubリポジトリ、CodeCommitリポジトリなど任意のコード保管場所を設定します。
        • 今回は、作成したCodeCommitリポジトリを選択します。
      • Name: Deploy
        • デプロイステージでは、pushされたコードをどこにデプロイするか選択します。
        • 今回は、CloudFormationスタックの作成と更新をさせたいので、Provider:ActionMode:で指定しておきます。
Resources:
  # ------------------------------ #
  # CodeCommitRepository
  # ------------------------------ #
  MyCodeCommitRepository:
    Type: AWS::CodeCommit::Repository
    Properties:
      RepositoryName: !Ref MyCodeCommitRepoName

  # ------------------------------ #
  # CodePipeline
  # ------------------------------ #
  MyPipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      Name: MyPipeline
      RoleArn: !GetAtt PipelineRole.Arn
      ArtifactStore:
        Type: S3
        Location: my-pipeline-bucket-name
      Stages:
        - Name: Source
          Actions:
            - Name: SourceAction
              ActionTypeId:
                Category: Source
                Owner: AWS
                Version: "1"
                Provider: CodeCommit
              Configuration:
                RepositoryName: !Ref MyCodeCommitRepoName
                BranchName: main
              OutputArtifacts:
                - Name: !Ref MySourceArtifact
        - Name: Deploy
          Actions:
            - Name: DeployAction
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Version: "1"
                Provider: CloudFormation
              Configuration:
                StackName: !Sub "${Env}-stack-${ResourceName}"
                ActionMode: CREATE_UPDATE
                Capabilities: CAPABILITY_IAM
                RoleArn: !GetAtt DeployRole.Arn
                TemplatePath: !Sub "${MySourceArtifact}::${MySourceTemplate}"
              InputArtifacts:
                - Name: !Ref MySourceArtifact

スタックの作成

早速、CloudFormationを使用してリソースを作成していきます。
手順は、以下の通りで、リンクにも詳細がございます。

  1. CloudFormation画面を開きスタックの作成>新しいソースを使用(標準)を選択
  2. テンプレートの準備完了>テンプレートファイルのアップロードを選択して、保存したymlを選択
  3. スタックに任意の名称を入力して、パラメータは環境に合わせて変更>次へを選択。※後述の手順に従う場合、デフォルト値でOK
  4. スタックオプションは特に変更せず、次へを選択
  5. レビュー画面を確認して送信を選択

リソースが作成される

CloudFormationスタックを実行すると、以下のように、CodeCommitリポジトリと CodePipelineが構築されました。

  • CodeCommitリポジトリ
  • CodePipeline

動作検証

では、早速、コードをpushしてみましょう。

コードをpush

冒頭で用意したS3バケットを作成するYAMLファイルを、CloudFormationで作成したCodeCommitリポジトリにpushします。

git push origin {ブランチ名}

CodeCommitへのpush方法は以下を参考にしてください。

CodePipeline画面を開くと、ソースステージでコードを変更を検知していることがわかります。

しばらくするとデプロイステージに遷移しました。
CloudFormationスタックの作成が進んでいます。
CloudFormationのコンソールで確認できるログが、CodePipeline画面からも確認できます。※もちろん、CloudFormationコンソールを開いてもリアルタイムで作成が進んでいることがわかります。

デプロイが完了しました。
S3画面を開くと確かに指定した名前でS3バケットが作成されています。

コードを変更してみる

では、今度は、コードに変更を加えて再度pushしてみましょう。
変更点はシンプルにタグを付与するだけです。

Resources:
  testBucket:
    Type: AWS::S3::Bucket
    Properties:
      Tags:
        - Key: "Name"
          Value: "UpdateComplete"

変更前は、スタックで作成された際に付与される3つのタグのみです。

では、pushします。

git push origin {ブランチ名}

パイプラインがコードの変更を検知しました。

デプロイまで完了したようです。

S3バケットのプロパティタブを確認すると、問題なくタグが付与されています。

まとめ

今回は、CodePipelineを用いて、デプロイ自動化の仕組みを構築しました。
これでインフラのコード化がさらに捗りそうです!これからも使っていきたいと思います。
最後までご覧いただきありがとうございました。

コメント

タイトルとURLをコピーしました