サポート
はじめに

Terraform と CI でリダイレクトをコードとして管理する

直接回答

RedirHub には、Terraform Registry で提供される公式 Terraform プロバイダー redirhub/redirhub があります。各リンクは 1 つの redirhub_link リソースです。対象は、ドメインリダイレクト、Web サイト移行のマッピング、ブランド短縮リンク、QR コードです。ドメインは redirhub_domain で、必要な DNS レコードも含みます。変更内容は pull request 内で plan として確認し、API トークンを使って CI から適用できます。API を含むすべてのプランで動作します。Core、Pro、Enterprise です。

1. プロバイダーをセットアップする#

API トークンの作成と管理 に記載されているとおりにトークンを作成します。トークンは 1 つの workspace に属し、Terraform はその workspace を管理します。ファイルに書き込むのではなく、REDIRHUB_API_TOKEN 環境変数で渡してください。

hclterraform {
  required_providers {
    redirhub = {
      source  = "redirhub/redirhub"
      version = "~> 0.1"
    }
  }
}

# REDIRHUB_API_TOKEN からトークンを読み取ります。
provider "redirhub" {}
bashexport REDIRHUB_API_TOKEN="your-token"
terraform init

2. リダイレクト、短縮リンク、QR コードを追加する#

handler はリンクの種類を示します: redirect、migration、short-url、qr です。Redirect と migration のマッピングは url を受け取り、応答先となる元の URL を指定します。Short link と QR code は host を受け取り、これは短縮リンク用ドメインの 1 つで、必要に応じて alias を指定できます。その他の属性は API と同じフィールドです: destinations、type、forward_path、forward_query、status、tags、utm です。

hcl# ドメイン全体を新しい移転先へ送ります。パスとクエリも含まれます。
resource "redirhub_link" "old_domain" {
  handler       = "redirect"
  url           = "old-site.com"
  destinations  = ["https://new-site.com"]
  type          = "301"
  forward_path  = true
  forward_query = true
}

# Web サイト移行: 古いページごとに 1 件のマッピングを作成し、設定ファイルの横の CSV に保持します。
resource "redirhub_link" "migration" {
  for_each = { for row in csvdecode(file("${path.module}/redirects.csv")) : row.from => row }

  handler      = "migration"
  url          = each.value.from
  destinations = [each.value.to]
  type         = "301"
}

# ブランド短縮リンクと動的 QR コード。
resource "redirhub_link" "spring" {
  handler      = "short-url"
  host         = "go.example.com"
  alias        = "spring"
  destinations = ["https://example.com/campaigns/spring"]
  utm          = { source = "newsletter", campaign = "spring" }
}

resource "redirhub_link" "menu" {
  handler      = "qr"
  host         = "go.example.com"
  alias        = "menu"
  destinations = ["https://example.com/menu"]
  qr           = { theme = "dark", logo = true }
}

terraform plan を実行すると変更内容を確認でき、terraform apply で変更を適用できます。Terraform は送信前に各リンクのフィールドをチェックするため、url のない redirect や host のない QR コードは plan の時点で失敗します。tags や、対応していないプランで複数の destinations を使う場合のようなプラン制限は、ダッシュボードと同じメッセージで返されます。

3. ドメインとそのDNSを同じ apply で接続する#

redirhub_domain はドメインを接続し、必要な DNS レコードを dns_records に返します。それらを DNS プロバイダーの Terraform リソースに渡してください。redirhub_domain_verification はレコードが有効になるまで待機するため、ドメインを使うリンクは応答が返るまで公開されません。既定の待機時間は 10 分です。DNS が遅い場合はタイムアウトを延長してください。

hclresource "redirhub_domain" "go" {
  host        = "go.example.com"
  short_links = true
}

# Here with Cloudflare; any DNS provider with a Terraform record resource works the same way.
resource "cloudflare_dns_record" "redirhub" {
  for_each = { for r in redirhub_domain.go.dns_records : "${r.type}-${r.name}" => r }

  zone_id = var.cloudflare_zone_id
  name    = each.value.name
  type    = each.value.type
  content = each.value.value
  ttl     = 300
}

resource "redirhub_domain_verification" "go" {
  host       = redirhub_domain.go.host
  depends_on = [cloudflare_dns_record.redirhub]
}

resource "redirhub_link" "launch" {
  handler      = "short-url"
  host         = redirhub_domain_verification.go.host
  alias        = "launch"
  destinations = ["https://example.com/launch"]
}

4. 既存のリンクを Terraform 管理下に取り込む#

ダッシュボードで作成したリンクはそのまま機能し続けます。Terraform で管理するには、ダッシュボードや API に表示される id、たとえば link_7bXmR4 で import してください。ドメインはホスト名で import します。redirhub_links データソースは、handler、host、tags など API と同じフィルターで id 一覧を返します。

hcldata "redirhub_links" "old_site" {
  handler = "redirect,migration"
  host    = "old-site.com"
}

output "old_site_ids" {
  value = { for l in data.redirhub_links.old_site.links : l.url => l.id }
}

# Terraform 1.5 and later: import in the plan, then manage it as usual.
import {
  to = redirhub_link.old_domain
  id = "link_7bXmR4"
}

ダッシュボードで後から誰かが変更した内容は、次の plan に反映され、terraform apply によってファイルの内容どおりに戻されます。ファイルから削除されたリンクは、次の apply で削除されます。

5. プルリクエストで plan し、マージ時に apply する#

設定はリポジトリ内のフォルダに置き、Terraform の state は S3 や HCP Terraform などのリモート backend に保存してください。トークンは CI の secret として保存します。この GitHub Actions ワークフローは、すべてのプルリクエストで plan を投稿し、プルリクエストがマージされたときに apply します。GitLab CI のパイプラインは provider's examples にあります。

yaml# .github/workflows/redirects.yml
name: Redirects
on:
  pull_request:
    paths: ['redirects/**']
  push:
    branches: [main]
    paths: ['redirects/**']
permissions:
  contents: read
  pull-requests: write
concurrency: redirects
jobs:
  terraform:
    runs-on: ubuntu-latest
    defaults:
      run:
        shell: bash
        working-directory: redirects
    env:
      REDIRHUB_API_TOKEN: ${{ secrets.REDIRHUB_API_TOKEN }}
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
        with:
          terraform_wrapper: false
      - run: terraform init -input=false
      - run: terraform plan -input=false -no-color -out=tfplan | tee plan.txt
      - if: github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const plan = require('fs').readFileSync('redirects/plan.txt', 'utf8');
            await github.rest.issues.createComment({ ...context.repo, issue_number: context.issue.number, body: '```\n' + plan.slice(-60000) + '\n```' });
      - if: github.event_name == 'push'
        run: terraform apply -input=false tfplan

再実行しても安全#

CIジョブはタイムアウトして再試行されます。プロバイダーが作成するすべてのリンクには Idempotency-Key が付与されるため、応答が戻る途中で失われても、再試行では 2つ目のコピーではなく RedirHub がすでに作成したリンクが返されます。レート制限と一時的なサーバーエラーは自動的に再試行されます。あなたのスクリプトでも同じことができます。POST の Idempotency-Key ヘッダーに一意の値を送信すれば、24時間以内に同じキーを使った場合は最初の応答が返され、Idempotent-Replayed: true と記されます。

bashcurl -X POST "https://api.redirhub.com/v1/links" \
  -H "Authorization: Bearer $REDIRHUB_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"handler": "redirect", "url": "old-site.com", "destination": "https://new-site.com"}'

すべての属性は Terraform Registry のプロバイダードキュメント に一覧されています。Terraform を使わずに一回限りのジョブをスクリプト化するには、API でリダイレクトを一括作成、更新、削除する をご覧ください。

よくある質問

はい。公式プロバイダーは Terraform Registry の redirhub/redirhub です。リダイレクト、Web サイト移行のマッピング、ブランド短縮リンク、QR コード、ドメインを管理します。

API を含むすべてのプランで利用できます。Core、Pro、Enterprise です。タグや複数の宛先などのプラン上限は、ダッシュボードと同様に適用されます。

はい。各リンクを id で、または各ドメインを hostname でインポートできます。redirhub_links データソースは、ドメイン上またはタグ付きのリンクの id を一覧表示します。

二重に作成されることはありません。ファイルに変更がない状態で 2 回目の apply を行っても何も変わりませんし、再試行された create には同じ Idempotency-Key が使われるため、RedirHub は既に作成済みのリンクを返します。

OpenTofu では source = "registry.terraform.io/redirhub/redirhub" を指定してプロバイダーを使えます。Pulumi や他のツールでは API を使ってください。Bearer トークンを用いた HTTPS 上のプレーンな JSON です。