🏃

キャッシュを利用したCircleCIのスピードUP

2023/09/02に公開

概要

下記の記事でCircleCIでawspecを利用したテストの実行を書きました。
https://zenn.dev/jnxjez/articles/aa4b441571ef91

CircleCIを実行していると実行時間が気になってきました。
どこで時間がかかっているのか確認すると、以下のように94s中79s(84.0%)がInstall awspecでした。

このawspecのインストールにキャッシュを使用することで49s中22s(44.9%)に実行時間を短縮することができました。

変更内容

修正後の.circleci/config.yml

変更内容の説明の前に修正後のconfig.ymlを記載します。

config.yml
config.yml
version: 2.1

orbs:
  aws-cli: circleci/aws-cli@4.0.0

jobs:
  cfnlint:
    docker:
      - image: cimg/python:3.11.4
    steps:
      - checkout
      - run:
          name: Install cfn-lint
          command: pip3 install cfn-lint==0.79.7
      - run:
          name: Execute cfn-lint
          command: cfn-lint ./CFn/Vpc.yml
          
  vpcstack:
    executor: aws-cli/default
    steps:
      - checkout
      - aws-cli/install
      - aws-cli/assume_role_with_web_identity:
          role_arn: $AWS_OIDC_ROLE_ARN
      - run: 
          name: Deploy VPC
          command: aws cloudformation deploy --template-file ./CFn/Vpc.yml --stack-name VpcStack  --no-fail-on-empty-changeset --region ap-northeast-1
  
  awspec:
    docker:
      - image: cimg/ruby:3.1.4
    steps:
      - checkout
      - aws-cli/install
      - aws-cli/assume_role_with_web_identity:
          role_arn: $AWS_OIDC_ROLE_ARN
      - restore_cache:
          keys:
            - gem-cache-v1-7D3BVdPh3Hl8dCWDU5_RSx5j2_ZTWw+VzNjVff_VT2Q=
            - gem-cache-v1-
      - run:
          name: Install awspec
          command: bundle install --path /home/circleci/project/vendor/bundle
      - run:
          name: Clean bundle
          command: bundle clean --force
      - save_cache:
          key: gem-cache-v1-{{ checksum "Gemfile.lock" }}
          paths:
            - /home/circleci/project/vendor/bundle
      - run:
          name: execute awspec
          command: |
            export AWS_REGION=ap-northeast-1
            cd ./awspec
            bundle exec rake spec
      
workflows:
  lint:
    jobs:
      - cfnlint:
          filters:
            branches:
              only:
                - test

  lint_deploy_test:
    jobs:
      - cfnlint:
          filters:
            branches:
              only:
                - main

      - vpcstack:
          requires:
            - cfnlint
          filters:
            branches:
              only:
                - main

      - awspec:
          requires:
            - vpcstack
          filters:
            branches:
              only:
                - main

Gemfile作成

config.ymlの中で以下のコマンドを実行してawspecをインストールしていましたが、Gemfileに切り出します。

gem install awspec -v 1.29.2
Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

gem "awspec","1.29.2"
gem "rake","13.0.6"
gem "rexml","3.2.5"

config.ymlの修正内容

diffの結果を以下に記載します。

diffの結果
@@ -35,16 +35,27 @@ jobs:
       - aws-cli/install
       - aws-cli/assume_role_with_web_identity:
           role_arn: $AWS_OIDC_ROLE_ARN
+      - restore_cache:
+          keys:
+            - gem-cache-v1-7D3BVdPh3Hl8dCWDU5_RSx5j2_ZTWw+VzNjVff_VT2Q=
+            - gem-cache-v1-
       - run:
           name: Install awspec
-          command: gem install awspec -v 1.29.2
+          command: bundle install --path /home/circleci/project/vendor/bundle
+      - run:
+          name: Clean bundle
+          command: bundle clean --force
+      - save_cache:
+          key: gem-cache-v1-{{ checksum "Gemfile.lock" }}
+          paths:
+            - /home/circleci/project/vendor/bundle
       - run:
           name: execute awspec
           command: |
             export AWS_REGION=ap-northeast-1
             cd ./awspec
-            rake spec
-
+            bundle exec rake spec
+      
 workflows:
   lint:
     jobs:

awspecのリストア

以下でawspecをキャッシュからリストアします。
「7D3BVdPh3Hl8dCWDU5_RSx5j2_ZTWw+VzNjVff_VT2Q=」の部分は、この後に記載するsave_cacheを一度実行し、その出力を確認して記載しています。

+      - restore_cache:
+          keys:
+            - gem-cache-v1-7D3BVdPh3Hl8dCWDU5_RSx5j2_ZTWw+VzNjVff_VT2Q=
+            - gem-cache-v1-

awspecのインストール

キャッシュするためにawspecをインストールします。
Gemfileを使ったインストールに変更したので、bundle installを実行します。

       - run:
           name: Install awspec
-          command: gem install awspec -v 1.29.2
+          command: bundle install --path /home/circleci/project/vendor/bundle
+      - run:
+          name: Clean bundle
+          command: bundle clean --force

awspecのキャッシュ

キャッシュのkeyにchecksum "Gemfile.lock"の結果を使います。

+      - save_cache:
+          key: gem-cache-v1-{{ checksum "Gemfile.lock" }}
+          paths:
+            - /home/circleci/project/vendor/bundle

この結果をrestore_cacheで使うための設定方法がわからず、一度実行してその結果をrestore_cacheに反映しています。
下図(CircleCIの実行結果)の3行目にchecksum "Gemfile.lock"の値が表示されています。
(gem-cache-v1-の後ろの部分)

変更後の実行結果

今回の変更で実行時間を94sから49sに短縮することができました。
キャッシュを使うことでInstall awspecは79sから22sに短縮できています。

Discussion