CircleCIのSelf Hosted Runnerを設定してみた

CircleCIにはCircleCIのサーバーでビルドする方法の他に、AWSなどの外部サーバーを接続して実行するSelf Hosted Runnerという機能があります。
2023.10.19

ゲームソリューション部の出村です。今回はCircleCIのSelf Hosted RunnerをEC2に対して設定してみました。CircleCIは軽く使ったことはあるものの、Self Hosted Runnerは今回初めて使いました。設定方法などいくつか分からなかった事があったので記録しておきます。

Self Hosted Runnerとは

Self Hosted Runnerとはビルドの実行環境をオンプレミスサーバーやAWSなどのCircleCI以外の環境で実行する方法です。これにより、特定環境を利用しないとビルドできない場合などに活用することができます(画像は、CircleCIのドキュメントより)。

この外部サーバーは以下の2種類から選択できます。今回はMACHINE RUNNERを使いました。MACHINE RUNNERは同時に1環境しか利用できないのに対して、CONTAINER RUNNERはコンテナですので同時に複数環境が利用できるというメリットがあります。目的に応じて使い分けるとよいでしょう。

MACHINE RUNNER : EC2のようなホストマシンに接続する方法
CONTAINER RUNNER : Kubernetesのコンテナを利用する方法

公式ドキュメントもありますので併せて参照するとよいでしょう。

対象環境

CircleCIからIntelサーバーで動作するAmazon Linux 2ベースのEC2に接続するようにしてみました。

設定方法

では設定を進めていきます。

CircleCIの設定

CircleCI側で Self Hosted Runnerの接続に必要な設定を行います。CLIから行う方法もありますが、今回はWebアプリケーションを利用します。

Self Hosted Runnerの画面にあるCreate Resource Classを選択します。

進めていくと、Custom Resource Classを定義する画面へ遷移するので設定します。接続先サーバーや用途などが分かるように命名しておくとよいでしょう。

今回は、cmdemura/blogentryとします。この名称は、後で開発プロジェクトに含まれるconfig.yamlファイルで指定することになります。

設定を保存すると、接続先のサーバー(今回の場合はEC2)の設定に必要なトークンが表示されます。このトークンは、今しか表示されませんので必ず記録を残しておきましょう。接続先サーバーの構築時に必要となります。

あとは、サーバー側の設定となります。先ほどのページをスクロールしていくと、設定手順が表示されていますので、その手順に沿ってスクリプトを実行していけばサーバーの設定が完了します。

以下のセットアップはIntelベースのAmazon Linux2に向けた手順となります。ドキュメントでは「Linux」「CentOS/RHEL」で実行するセットアップ内容となります。

ファイルのダウンロード

最初に必要なファイルをダウンロードします。

# For Linux x86_64:
export platform=linux/amd64 && sh ./download-launch-agent.sh

CircleCI agentのセットアップ

CircleCIのエージェントが動作している必要がありますので、それに必要な設定を行います。

次に、CircleCIのユーザー作成とワーキングディレクトリを作成します。

id -u circleci &>/dev/null || sudo adduser -c GECOS circleci

sudo mkdir -p /var/opt/circleci
sudo chmod 0750 /var/opt/circleci
sudo chown -R circleci /var/opt/circleci /opt/circleci/circleci-launch-agent

次にCircleCI Runnerの設定ファイルを作成します。設定ファイル(launch-agent-config.yaml)のアクセス権限が600となっているのでそれを最後に確認しておきましょう。

sudo mkdir -p /etc/opt/circleci
sudo touch /etc/opt/circleci/launch-agent-config.yaml
sudo chown circleci: /etc/opt/circleci/launch-agent-config.yaml
sudo chmod 600 /etc/opt/circleci/launch-agent-config.yaml

設定ファイルの内容は、以下のようになります。

ここでの変更箇所は2点あります。auth_tokenは、先ほど取得したトークンを指定します。次にrunnerに含まれるnameですが、こちらは何かの設定と一致させる必要は無く任意の文字列となります。それ以外の項目は変更しなくてもよいです。

api:
  auth_token: 9b55028b53eb72b2011bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

runner:
  name: RUNNER_NAME
  working_directory: /var/opt/circleci/workdir
  cleanup_working_directory: true

systemdの設定

次に起動の設定をsystemdに対して行います。まず起動設定のファイルを用意します。

sudo touch /usr/lib/systemd/system/circleci.service
sudo chown root: /usr/lib/systemd/system/circleci.service
sudo chmod 644 /usr/lib/systemd/system/circleci.service

circleci.serviceの内容は以下の通りです。

[Unit]
Description=CircleCI Runner
After=network.target
[Service]
ExecStart=/opt/circleci/circleci-launch-agent --config /etc/opt/circleci/launch-agent-config.yaml
Restart=always
User=circleci
NotifyAccess=exec
TimeoutStopSec=18300
[Install]
WantedBy = multi-user.target

あとは、このciecleciのサービスがサーバー起動時に起動するように設定します。

sudo systemctl enable circleci.service

サーバー起動時に自動的に起動するよう設定しておきます。

sudo systemctl start circleci.service

これで正常に接続されていると、CircleCIのSelf Hosted Runnerで接続先のサーバーが表示されます。

config.ymlファイルの設定内容

次にプロジェクト内にあるconfig.ymlファイルの設定方法をみていきます。このconfig.ymlでは、resource_classとして接続先サーバー(今回はcmdemura/blogentry)を指定します。

version: 2.1
workflows:
  testing:
    jobs:
      - runner-test
jobs:
  runner-test:
    machine: true
    resource_class: cmdemura/blogentry
    steps:
      - run: echo "Hi I'm on Runners!"

実行する

あとは、いつもと同じように実行します。実行すると、先に指定したメッセージが表示されます。ここでビルドが完了しない場合はEC2に対して接続できていないので、その原因を調査する必要があります。

さいごに

まぁ、CircleCIのビルドだけでは何かと不便を感じている場合は、こちらのSelf Hosted Runnerを活用する事も検討してもよいかもしれません。