Amazon CodeCatalyst で AWS Lambda の CI/CD 環境を構築する

こんにちは。ひるたんぬです。

春が終わりを告げ、夏が近づいてきましたね。
最近はニュースや新聞などで「今年は最も暑い」や、「観測史上一番の暑さ」「季節外れの暑さ」など、連日ホットな話題が報道されています。野菜やオリーブオイルも高騰が続いており、最近は手に取るのを躊躇してしまいます。

…ところで、皆さんは「夏」と「冬」、どちらが好きですか?
私は圧倒的に冬派¹なのですが、周囲に聞く限り少数派のようでした。
¹ 冬派な理由としては、寒いのは「着ればなんとかなるから」です。暑いのには対処の限界がありますからね…

少し古い資料にはなりますが、日本リサーチセンターが2016年5月に行った調査によると、

  • 日本人全体でみれば、 「夏」が52%と半数を超えて、「冬」(21%)の倍以上多い
  • 性別でみると、男⼥ともに「夏」が優位だが、男性では58%と半数を超えて特に多い。
  • エリア別では、「夏」は東⾼⻄低の傾向がみられ、北海道・東北では6割を超える
  • 年代別でみても、いずれも「夏」が優位だが、15〜19才では「冬」が3割以上で比較的多い。

出典:日本リサーチセンター「【NRCレポート】あなたはどっち?日本人の好み調査 Part3:生活とライフスタイル」P.10

という結果でした。この結果を見る限り、夏派の方は涼しい地域の方に多い傾向があるので、夏が暑くなってきている今、その割合は減っているんでしょうかね?少しばかりですが気になります。

話題がそれてしまいましたが、本題に入ります。
今回は2023年4月にGAとなった「CodeCatalyst」を色々触ってみたので、それについてお話ししようと思います。

そもそも…CodeCatalystって?

CodeCatalystについて初めて耳にする方もいるかと思いますので、簡単にご説明いたします。

詳細について知りたい方は、Black BeltのCodeCatalystシリーズをご覧になることをおすすめします。(全部で9編あるので、中々のボリュームです。)

CodeCatalystを一言で表すと「統合ソフトウェア開発サービス」です。

出典:AWS「AWS Black Belt Online Seminar – Amazon CodeCatalyst Overview 編」P.11

これを聞くと、「既にCodeBuildやCodePipelineなどがあるじゃないか」と思う方もいると思います。個人的にはCode ○○が一つにまとまって提供されている点複数人での開発(コラボレーション)のしやすさにおいて、CodeCatalystの使いやすさがあるのではないかと思います。

やってみたこと

プライベートで作りたいものがあったので、CodeCatalystを開発環境に設定し開発を進めました。
開発を進める中で、せっかくならCI/CDについても勉強したくなり、今回の記事を作成しております。

今回の記事では、下記フローを自動で行います。

前準備

CodeCatalystの利用にあたっては、AWS Builders IDの取得が必要です。
また、初期設定が必要となっておりますが、このあたりにつきましては参考サイトのご紹介のみさせていただきます。参考サイトなどをご覧の上、

  • 自分のCodeCatalyst Spaceを作成
  • CodeCatalystで使用するRoleを作成
  • 新規の空のプロジェクト(Start from scratchより)を作成

してください。

作成が終わったら、下記のようなProjectのページができていることを想定しています。

また、ソースコードの格納先である任意のS3バケットが必要です。
あらかじめ作成しておいてください。

バケットではバージョニングを有効にしてください。
CDを行う際にオブジェクトのバージョンが必要となるためです。

リポジトリの作成

今回はCodeCatalyst内にリポジトリを作成します。(GitHubのリポジトリを紐づけることも可能です。)
上図画面から「Source repositories」欄右上の「Add repository」→「Create repository」を選択してください。

リポジトリ作成画面で適切に情報を入力し、「Create」を押下します。
今回の手順ではPythonを用いるので、.gitignoreはPythonを選んでおくと良いと思います。

作成が完了すると、リポジトリが表示されます。

開発環境の準備

CodeCatalystでは、開発環境としてCloud9やVS Codeなどを選択できます。

左側ペインより「Code」→「Dev Environments」を選択し、「Create Dev Environment」を押下します。今回は「Visual Studio Code」を選択します。

Visual Studio Codeがインストールされていない、など利用ができない場合は、Cloud9を選択してください。本記事ではVisual Studio Codeの例を示しますが、手順は大きくは変わりません。

下図が表示されリポジトリに関する設定や、開発環境のリソースの設定ができます。
今回は特に設定を変更せず「Create」を押下します。

しばらく待つと、作成が完了した旨のメッセージが表示されるので、作成された開発環境の「Open in Visual Studio Code」を押下します。

はじめてCodeCatalystからVS Code環境に接続した際などに、拡張機能(AWS Toolkit)のインストールや初期設定を求められます。手順に従い対応してください。
VS Codeが起動し、左下に「SSH: aws-devenv-…」と表示があれば接続に成功しています。

ここで、検証用の簡単なファイルを作成します。今回は以下のサイトを参考に、fizzbuzz問題のプログラムを作成します。
また、ここで作成する「resource.yaml」は以下のコードを複製してください。
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
  BucketName:
    Type: String
  LambdaVersionId:
    Type: String
Resources:
  FizzBuzzFunction:
    Type: "AWS::Lambda::Function"
    Properties:
      Code:
        S3Bucket: !Ref BucketName
        S3Key: "Artifacts/src.zip"
        S3ObjectVersion: !Ref LambdaVersionId
      Environment:
        Variables:
          bucket_name: !Ref BucketName
      Handler: "get_index.lambda_handler"
      Runtime: "python3.12"
      Timeout: 10
      FunctionName: "FizzBuzz-Function"
      Role: !Ref FizzBuzzRole
  FizzBuzzFunctionLogGroup:
    Type: "AWS::Logs::LogGroup"
    Properties:
      LogGroupName: !Sub "/aws/lambda/${FizzBuzzFunction}"
      RetentionInDays: 30
  FizzBuzzFunctionVersion:
    Type: AWS::Lambda::Version
    Properties:
      FunctionName: !Ref FizzBuzzFunction
  FizzBuzzRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: Lambda-FizzBuzzRole
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
最終的にファイル構成が下図のようになっていればOKです。
ここまでできたら、一旦VS Codeの拡張機能「AWS Toolkit」を選択し、「CODECATALYST」→「Stop Dev Environment」を押下し、開発環境を一旦停止させます。
VS Codeを ✕ で閉じた場合、開発環境は稼働したままの状態になっています。
今回の設定(初期設定)では、非アクティブの場合、15分で自動停止されるようになっていますが、利用可能な時間枠を消費してしまいますのでご注意ください。
誤ってVS Codeを ✕ で閉じた場合は、CodeCatalystのページより該当の開発環境を選択し、「Stop」を押下することで停止させることができます。

環境の登録

リソースをデプロイする先のAWSアカウントをここで指定します。
左側ペインより「CI/CD」→「Environments」を選択し「Create environment」を押下します。

設定値は以下のようにしてください。

  • Environment name:分かりやすい名前を設定します。今回は「Dev」としました。
  • AWS account connection:ご自身のAWSアカウントIDを選択してください。

設定ができたら、「Create environment」を押下します。

CI/CDワークフローの構築

…ここからが本番ですね。笑
左側ペインより「CI/CD」→「Workflows」を選択し「Create workflow」を押下します。

workflowの作成画面で、先ほど作成したリポジトリを選択し、「Create」を押下します。

これにより、workflowが作成されました。

workflowはStep Functionsと同じように、ブロック(Visual)もしくはコード(YAML)で作成することができます。今回は初めてということもあるので、Visualで説明を進めます。

CI: Continuous Integration

上図のうち、「PC」と「Source Repositoiry」の部分については既に作成されています。
そのため、単体テストを行うための準備をします。

Test

Workflow編集画面の左上にある「Action」より、「Test」を探し、右下の「+」を押下します。
すると右側に設定項目が出てきますので、今回は以下に従って設定してください。

  • Inputs
    何も変更しません。
  • Configuration
    • Action name:分かりやすい名前に変更します。今回は「Test」としました。
    • Shell commands:以下のスクリプトを入力します。
- Run: pip install -r ./requirements.txt
- Run: PYTHONPATH=.
- Run: pytest --cov=src/ test --cov-report=xml
- Run: pytest --junitxml=./unit_test.xml
  • Packages
    何も変更しません。
  • Outputs
    何も変更しません。

CD: Continuous Deployment

単体テストを終えた作成物については、承認を挟んだ後にデプロイをするという流れを取っています。

Approval

先ほどの「Actions」の横にある「Gates」から「Approval」を追加します。
右側に出てくる設定項目を以下の通りに設定してください。

  • Inputs
    何も変更しません。「Depends on」に、先ほどの「Test」が設定されていることを確認してください。
  • Configuration
    • Gate name:分かりやすい名前に変更します。今回は「Approval」としました。
Deploy

今回はCloudFormationでのデプロイを行います。
そのため、ここでは

  1. リソースファイル(resource.yaml)と、ソースコードをS3にアップロードする
  2. ソースコードのオブジェクトバージョンを取得
  3. リソースをデプロイ

の3つに分けて手順をご説明します。

1. S3へのアップロード

「Actions」から「Build」を探し、追加します。
右側に出てくる設定項目を以下の通りに設定してください。

  • Inputs
    • Variables:以下のキーと値を設定してください。
      • キー:bucket_name
      • 値:(ソースコードなどを保管するバケット名)
    • Depends on:「Approval」を選択してください。
  • Configuration
    • Action name:分かりやすい名前に変更します。今回は「TransferArtifactsToS3」としました。
    • Environment:「Dev」を選択します。
    • AWS account connection:ご自身のAWSアカウントIDを選択します。
    • Role:事前準備で作成したロールを選択します。
    • Shell commands:以下のスクリプトを入力します。
- Run: sudo yum install zip -y
- Run: cd ./src
- Run: zip ./src.zip *.py
- Run: cd ../
- Run: aws s3 mv ./resource.yaml s3://${bucket_name}/Resources/resource.yaml
- Run: aws s3 mv ./src s3://${bucket_name}/Artifacts/ --recursive --include "*"
  • Packages
    何も変更しません。
  • Outputs
    • Variables:「Add variables」を押下し、Nameに「bucket_name」と入力します。
2. オブジェクトバージョンを取得

先ほどと同様に「Actions」から「Build」を探し、追加します。
右側に出てくる設定項目を以下の通りに設定してください。

先程のS3へのコピーと同じブロックで実行しても良いのですが、分かりやすさのために、あえて分けてます。
  • Inputs
    • Depends on:「TransferArtifactsToS3」を選択してください。
  • Configuration
    • Action name:分かりやすい名前に変更します。今回は「GetObjectVersion」としました。
    • Environment:「Dev」を選択します。
    • AWS account connection:ご自身のAWSアカウントIDを選択します。
    • Role:事前準備で作成したロールを選択します。
    • Shell commands:以下のスクリプトを入力します。
- Run: src_info=$(aws s3api list-object-versions --bucket ${TransferArtifactsToS3.bucket_name} --prefix Artifacts/src.zip)
- Run: src_version=$(echo ${src_info} | jq '.Versions[] | select(.IsLatest) | .VersionId')
- Run: echo '{"Parameters":{"LambdaVersionId":'$src_version', "BucketName":"${TransferArtifactsToS3.bucket_name}"}}' | jq > ./version.json
  • Packages
    何も変更しません。
  • Outputs
    • Artifacts:「Add artifact」を押下します。
      • Build artifact name:分かりやすい名前を設定します。今回は「ArtifactVersion」としました。
      • Files produced by build:「./version.json」と入力します。
3. リソースのデプロイ

「Actions」から「Deploy AWS CloudFormation stack」を探し、追加します。
右側に出てくる設定項目を以下の通りに設定してください。

  • Inputs
    • Artifacts:「ArtifactVersion」を選択してください。
    • Depends on:「GetObjectVersion」を選択してください。
  • Configuration
    • Action name:分かりやすい名前に変更します。今回は「DeployAWSCloudFormationStack」としました。
    • Environment:「Dev」を選択します。
    • AWS account connection:ご自身のAWSアカウントIDを選択します。
    • Role:事前準備で作成したロールを選択します。
    • Stack name:適当なスタック名を入力します。今回は「Lambda-CICD」としました。
    • Stack region:スタックをデプロイしたいリージョンを選択してください。東京リージョンでも問題ありません。
    • Template:「./resource.yaml」と入力します。
    • Advanced:オプションを展開し、以下を設定します。
      • Capabilities:IAMリソースを作成するため、「CAPABILITY_NAMED_IAM」にチェックを入れます。
      • Parameter overrides:オブジェクトバージョンを上書きするため、以下のように設定します
        • 「Specify overrides using a file」を選択
        • ファイル名:file:///artifacts/DeployAWSCloudFormationStack/ArtifactVersion/version.json

なお、パラメータの上書きについては以下のドキュメントを参考にしました。

すべてが完了したら、下図のようなフローが出来上がっていると思います。

確認ができたら左上の「Commit」を押下します。するとフローが動き出し、テストを開始します。

フローの進捗状況確認

左ペインより「CI/CD」→「Workflows」を選択することで確認できます。

また、それぞれのリンクをクリックすることで詳細な進捗を確認できます。

テスト結果の確認

フローの「Test」をクリックすると、テストの詳細を確認できます。例えば「Reports」タブをクリックすると、行われたテストの結果やカバレッジをひと目で確認することができます。

承認

今回は「Test」のあとに承認(Approval)を追加しているので、単体テスト終了後にApprovalを選択すると、以下のような画面が表示されます。

ここでテストのレビューを行い、承認するかどうかを選びます。

承認する(Approve)と先のフローに進み、却下する(Reject)とそこでフローが終了します。

デプロイ確認

フローが最後まで完了すると、指定したAWS環境にリソースがデプロイされています。
マネジメントコンソールのCloudFormationから、もしくはWorkflowの最後のブロック(DeployAWSCloudFormationStack)選択し、「Summary」タブを押下することで確認することができます。

おわりに

今回は比較的新しいサービスに触れてみました。
公式ドキュメントが英語であったり、「やってみた」というような記事が少なかったため試行錯誤するところが多かったです。
また、私自身CI/CDの枠組みに初めて触れてみて、改めて自動化の簡単さ・便利さに気づくことができました。

▼ 今回参考にした、数少ない日本語の公式ブログです。

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