CircleCI の Scheduled Pipelines で restricted context を使う処理をスケジュール実行する

## はじめに

この記事は[CircleCI Advent Calendar 2021](https://qiita.com/advent-calendar/2021/circleci)の20日目の記事です。

CircleCIでカスタマーサクセスをしている鈴木と申します。今年の出来事としては、アンパンマンの絵本に出てくる「きんぴらたべたいおじいさん」というキャラクターが正式な名前なのか気になって検索してみたら過去に[矢井田瞳さんも言及していた](https://twitter.com/yaiko_official/status/219754290955288577?s=20)ということがありました。

さて、CircleCIでは config.yml 内に crontab 形式の構文を記述することでワークフローをスケジュール実行することができます。このスケジュールワークフローはよく利用されている機能の一つですが、いくつか改善のご要望をいただいていました。そのご要望に応えるためにリリースしたScheduled Pipelines という機能を取り上げます。

## 従来の cron キーによるスケジュール実行と制約 
従来の[スケジュールワークフロー](https://circleci.com/docs/ja/2.0/workflows/#scheduling-a-workflow)をおさらいしておきます。以下は config.yml の一部ですが、triggers, schedule, cron といったキーを用いて設定します。

```
workflows:
  version: 2
  my-nightly-build:
    triggers:
      - schedule:
          cron: "0 0 * * *"  # 時刻の基準はUTCです
          filters:
            branches:
              only:
                - main
    jobs:
      - test
```

config.yml 内の記述で管理できる点はシンプルなのですが、スケジュールワークフローには以下のような制約があります。

- Dynamic Config や restricted context などと併用できない
- スケジュール変更のために config.yml を編集しなければいけない
- ワークフロー単位での設定なので、複数のワークフローが存在する場合、それぞれに設定を記述しなければいけない

なかでも「スケジュールワークフローで restricted context を利用できない」という制約への改善要望は、[CircleCI Ideas](https://circleci.canny.io/) という CircleCI への機能リクエストを集約している場所でも[多くの票を集めていました](https://circleci.canny.io/cloud-feature-requests/p/allow-restricted-contexts-within-scheduled-workflows)。[^1] 

ここでは restricted context （制限付きコンテキスト）について詳述しませんが、複数のプロジェクト（リポジトリ）で共通して利用する環境変数やクレデンシャル情報を登録して利用する context という機能があり、その context を利用できるユーザーを制限したものが restricted context です。[^2]

従来のスケジュールワークフローの場合、CircleCIのシステムが「Scheduled」という名称でスケジュールの実行者となるため、restricted context の参照を許可しているユーザーになることができず、「Unauthorized」というステータスのエラーになります（下図）。
![failed_scheduled_workflow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11243/db7a6919-0621-42a5-153a-2d981c8f253d.png)


## Scheduled Pipelines

それでは、 restricted context を使う処理でもスケジュール実行できる Scheduled Pipelines を見ていきます。

設定は API か GUI で行います。[CircleCIの公式ブログ](https://circleci.com/blog/using-scheduled-pipelines/)では両者を説明していますが、ここでは GUI での設定にのみ触れます。

Scheduled Pipelines の設定画面への行き方ですが、まず、Dashboard で対象のプロジェクト（リポジトリ）に絞り込みます。すると、右上に「Project Settings」というボタン（下図矢印部分）が表示されるのでそこをクリックします。
![project settings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11243/78759cba-5f66-90bc-f45c-0e089c7cff3b.png)

Project Settings のサイドメニューにある「Triggers」が Scheduled Pipelines の設定です。（UI では Scheduled Pipelines ではなく Scheduled Triggers と表記されていますが、気にせず進みます。）「Add Scheduled Trigger」という青いボタンをクリックします。
![triggers.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11243/2d166acc-d2ec-b73a-83a8-546c909b58d1.png)

下図がスケジュールの設定画面です。わかりやすい項目が並んでいると思いますので、ここでは2箇所についてのみ補足します。
![trigger settings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11243/695a408e-fe80-5107-b0f9-02bee4ef0ec3.png)

1つ目は 「Add Pipeline Parameters」です。今回は触れませんが、パイプラインの中に複数のワークフローが存在して、一部のワークフローのみスケジュール実行したいといった制御などに利用します。前述の[CircleCIの公式ブログ](https://circleci.com/blog/using-scheduled-pipelines/)のサンプルでは "run-schedule" というパラメーターを以下のように設定しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11243/316eb3f3-65a5-4365-af92-a6b49965f9cb.png)

2つ目は「Attribution」です。スケジュール処理の実行者を、「Scheduled Actor」か「Me (自分のアカウント)」かのどちらかを選択します。ここで「Me」を選択し、かつ、自分自身が restricted context へのアクセスを持っている場合に、**「restricted context を使う処理をスケジュール実行する」ことができます。**[^3]

## さいごに

簡単に Scheduled Pipelines を紹介しました。文中でも登場した[CircleCIの公式ブログ](https://circleci.com/blog/using-scheduled-pipelines/)の記事では、config.yml 内に crontab 形式の構文を記述するスケジュールワークフローによる設定を Scheduled Pipelines へ書き換える方法についても触れています。明確な日程はまだお伝えできませんが、従来のスケジュールワークフローはいずれ「非推奨」となり、2022年6月頃に動作をサポートしなくなる予定です。お早めに Scheduled Pipelines への移行をご検討ください。

さて、2021年を振り返りますと、私生活で大きなタスクがあり、CI/CDを始めとする技術的な学習の時間を持つことがなかなかできませんでした。来年4月頃から改善できそうなので良い年にしたいです。


[^1]: CicleCI Ideas には、他のユーザーが投稿した機能リクエストに賛同を示す投票機能があります。票が多い要望ほど製品チームの目に留まるので、欲しい機能が投稿されていたら皆さんも投票してください。投稿されていなかったら新規で投稿いただけると嬉しいです。投稿すべきかどうか迷ったら私やサポートチームにご相談ください。

[^2]: 2020年の [CircleCI Advent Calendar](https://qiita.com/advent-calendar/2020/circleci) で書いた「[CircleCIの承認ジョブの承認者を限定したい](https://qiita.com/suzucir/items/878b90f32c0f7ef4b3a6)」でも restricted context に触れています。

[^3]: 「Attribution」で「Me」を選択した場合、つまり、Scheduled Pipelines の実行者に特定のユーザーを指定した場合、そのユーザーが Organization を離れると Scheduled Pipelines の実行者が見つからないのでエラーになります。restricted context を使用しないのであれば、「Scheduled Actor」を選んでおいたほうが良いかもしれません。