Terraform CloudのRun Tasksを少し深掘りしてみた

# はじめに
みなさん、こんにちは。Terraform Cloud大好き@kuroseetsです。
今年も残すところあと1週間強ですか、早いものですね。
この記事はterraform Advent Calendar 2021の21日目の記事です。
Advent Calendarも今日を含めてあと5日、それまでのお付き合いよろしくお願いします。

さて今回の記事は、今秋 Terraform Cloud で実装された Run Tasks という機能について少し掘り下げて調べてみましたので紹介させていただきます。

# Run Tasksとは
現状はまだベータ版ではありますが、今年の9月に、Terraform Cloud Team & Governance, Terraform Cloud Business Tierを対象にリリースされました。
この機能を簡単に説明しますと、Terraform CloudのPlanとApplyの間で外部のシステムにイベントを送り、その返答を受け取る、というものです。
これによって、TerraformのPlan後、サードパーティー製や自作のデプロイツールなどに通知が行われ、Terraform外のデプロイの成否を受け取ることで、その後のApplyを継続するかどうかの判断をTerraformに持たせることを可能にしてくれます。

# 設定と動作確認
## 設定方法
[公式ページ](https://www.terraform.io/cloud-docs/workspaces/settings/run-tasks) にしっかり書かれていますので、この記事では割愛します。
基本的に画面をポチポチしていきます。


[Run Tasks API](https://www.terraform.io/cloud-docs/api-docs/run-tasks) は実装されていますが[Terraform Enterprise Provider](https://registry.terraform.io/providers/hashicorp/tfe/latest/docs) はまだ実装されていませんのでGAされたら・・・、というところですかね。

## 実際のやり取り
せっかくなので、どのようなリクエストが来るのかを覗いてみようと思いまして、受け取ったリクエストをログに落とすだけのWebサーバを構築し、上記手順ページの4番目で Endpoint URL にそのサーバを指定しました。
そしてApplyを実行するとPlanとApplyの間で処理を中断し、サーバ側で以下のリクエストを受け取りました。

```JSON
{
    "payload_version": "1",
    "access_token": "examplePo3Bodw.atlasv1.URceefTMN9cyJcSMZtoz1cjy29ORl8BU7H1AnvoPTwMfxWFUExOD1nLBFtA8example",
    "task_result_id": "taskrs-examplefXexample",
    "task_result_enforcement_level": "advisory",
    "task_result_callback_url": "https://app.terraform.io/api/v2/task-results/example3-6a0e-4645-aa10-30eb1example/callback",
    "run_app_url": "https://app.terraform.io/app/ORGNAME/WORKSPACENAME/runs/run-exampleZUexample",
    "run_id": "run-exampleZUexample",
    "run_message": "test",
    "run_created_at": "2021-mm-ddTHH:MM:SS.SSSZ",
    "run_created_by": "kuroseets",
    "workspace_id": "ws-exampletJexample",
    "workspace_name": "WORKSPACENAME",
    "workspace_app_url": "https://app.terraform.io/app/ORGNAME/WORKSPACENAME",
    "organization_name": "ORGNAME",
    "plan_json_api_url": "https://app.terraform.io/api/v2/plans/plan-exampleu3example/json-output",
    "vcs_repo_url": "https://github.com/GITORG/REPOSITORY.git",
    "vcs_branch": "main",
    "vcs_pull_request_url": "",
    "vcs_commit_url": "https://github.com/GITORG/REPOSITORY/-/commit/example3e1681e0e286ad0ad6f9caf56bexample"
}
```
外部側のアプリケーションは run_id や plan_json_api_url より REST API を使用して Plan を参照できるので、その結果如何で処理を継続するのかどうかを判断すれば良いのかなと思います。

停止中のTerraform Applyに通知するには access_token を使用して task_result_callback_url に PATCHメソッドでリクエストを送ります。
リクエストボディの data.type.attributes.status 処理の成功/失敗(passed/failed)の値になります。
以下のように適当な場所から curl をでリクエストを送ることで、Terraform側も処理を再開してくれることだと思います。

```BASH
curl \
  -X PATCH \
  --header "Authorization: Bearer examplePo3Bodw.atlasv1.URceefTMN9cyJcSMZtoz1cjy29ORl8BU7H1AnvoPTwMfxWFUExOD1nLBFtA8example" \
  --header "Content-Type: application/vnd.api+json" \
  -d '{
  "data": {
    "type": "task-results",
      "attributes": {
        "status": "passed",
        "message": "messages here"
      }
  }
}' \
  https://app.terraform.io/api/v2/task-results/example3-6a0e-4645-aa10-30eb1example/callback
```

# さいごに
Run Tasksは先ほども書きましたが、まだベータ版でGAされていません。
この機能の仕様も変更される可能性がありますし、サードパーディ製の拡充もこれからでしょう。
それでも、充実すれば便利だということは間違い無いと思います。
その他、Terraform Cloudは色々な機能拡充が行われていますので、来年も機会があればいろいろな調査してみたいですね。
それではみなさま、良いお年を！