直接回答
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 init2. リダイレクト、短縮リンク、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 です。
