😄

TerraformでVercelを構築するメモ

に公開

TerraformでVercelを構築するメモ

terraformでVercelのプロジェクトを構築できるらしいのでやってみた。Github Actionsなどからデプロイする方式を想定している。

プロバイダーの設定

api_token
Account SettingsページのTokenから作成したトークンを使用する

team_id
自身のユーザーが所属するチームIDを使用する

Team IDはsettingsタブ(タブメニューの右端)のGeneralページにTeam IDに書いてある

この2つは漏れるといけないのでterraform.tfvarsに記して変数から読み取るようにする

providers.tf
terraform {
  required_providers {
    vercel = {
        source = "vercel/vercel"
        version = "~> 2.0"
    }
  }
}

provider "vercel" {
  api_token = var.api_token
  team = var.team_id
}

変数

sensitiveフラグを立てることで出力に含まれずvalueが表示されないようになる

variables.tf
variable "api_token" {
  description = "Vercelのアクセストークン"
  type = string
  sensitive = true
}

variable "team_id" {
  description = "VercelのTeam ID"
  type = string
  sensitive = true
}

Vercel

vercel_project

  • プロジェクトリソースを作成する
  • Add Newでリポジトリを選んだりした後作成されるあれ

vercel_attack_challenge_mode

  • すべての訪問者に対して検証チャレンジを表示することで、悪意のあるトラフィックを防止
  • 訪問者にサイトアクセス前にセキュリティチャレンジが表示される

vercel_firewall_config

  • ファイアウォールの設定やカスタムルールを設定する
  • 下記では日本以外からのアクセスはすべてブロックする(おそらく)

vercel_project_environment_variables

  • プロジェクトの環境変数を設定する
  • vercel_project_environment_variablesvercel_project_environment_variableの2種類があり、併用すると変数が上書きされるため、注意が必要

vercel_project_domain

  • プロジェクトにドメインを関連付けるために使用する
  • redirectにドメイン名、redirect statusを指定するとそのドメインにリダイレクトする設定になる

コメントアウトしてあるのはカスタムドメインを付与するのに必要になるコード。AWSでドメインを購入した場合になるが、Vercelのネームサーバーを指定したAレコードを紐づける。

main.tf
resource "vercel_project" "test" {
  # カスタムドメインを自動で割り当てるかどうか
  auto_assign_custom_domains                        = true
  
  # システム環境変数を自動的に公開するかどうか
  automatically_expose_system_environment_variables = true
  
  # カスタマーサクセスチームがコードを閲覧できるかどうか
  customer_success_code_visibility                  = false
  
  # ディレクトリの一覧表示を許可するかどうか
  directory_listing                                 = false
  
  # 使用するフレームワーク(Next.jsを指定)
  framework                                         = "nextjs"
  
  # 関数のフェイルオーバー機能を有効にするかどうか
  function_failover                                 = false
  
  # Gitフォーク時の保護機能を有効にするかどうか
  git_fork_protection                               = true
  
  # Git LFS(Large File Storage)を有効にするかどうか
  git_lfs                                           = false
  
  # プロジェクト名
  name                                              = "test"
  
  # 使用するNode.jsのバージョン
  node_version                                      = "22.x"
  
  # OIDC(OpenID Connect)トークンの設定
  oidc_token_config = {
    # OIDCトークンを有効にするかどうか
    enabled     = false
    # 発行者モード(グローバルまたはプロジェクト固有)
    issuer_mode = "global"
  }
  
  # プロダクションビルドを優先するかどうか
  prioritise_production_builds = true
  
  # リソースの設定
  resource_config = {
    # 流動的なリソース割り当てを使用するかどうか
    fluid = false
  }
  
  # サーバーレス関数を実行するリージョン(iad1 = 米国東部)
  serverless_function_region = "iad1"
  
  # チームID(変数から取得)
  team_id                    = var.team_id
  
  # Vercel認証の設定
  vercel_authentication = {
    # デプロイメントタイプ
    deployment_type = "standard_protection"
  }
}

# 攻撃チャレンジモードの設定
resource "vercel_attack_challenge_mode" "test" {
  # プロジェクトID
  project_id = vercel_project.test.id
  
  # 攻撃チャレンジモードを有効にするかどうか
  enabled    = true
}

# ファイアウォール設定
resource "vercel_firewall_config" "test" {
  # プロジェクトID
  project_id = vercel_project.test.id
  
  # チームID
  team_id    = var.team_id

  # ファイアウォールルール
  rules {
    rule {
      # アクション設定
      action = {
        # 実行するアクション(拒否)
        action = "deny"
      }
      
      # 条件グループ
      condition_group = [{
        # 条件設定
        conditions = [{
          # 演算子(not equal = 等しくない)
          op    = "neq"
          # 条件のタイプ(地理的国家)
          type  = "geo_country"
          # 値(日本のISO国コード)
          value = "JP"
        }]
      }]
      
      # ルールの説明
      description = "Block all access from foreign countries"
      
      # ルール名
      name        = "Block all access from foreign countries"
    }
  }
}

# プロジェクト環境変数の設定
resource "vercel_project_environment_variables" "test" {
  # プロジェクトID
  project_id = vercel_project.test.id
  
  # 環境変数のリスト
  variables = [{
    # 環境変数のキー名
    key    = "NODE_ENV"
    # 環境変数の値
    value  = "production",
    # 適用対象環境
    target = ["production"]
    }, {
    key    = "NODE_ENV"
    value  = "development",
    target = ["preview"]
  }]
}

# Route53ゾーンの取得
# data "aws_route53_zone" "test" {
#   # ドメイン名
#   name = "test.com"
# }

# Route53レコードの作成
# resource "aws_route53_record" "test" {
#   # ゾーンID(上記で取得したゾーンを参照)
#   zone_id = data.aws_route53_zone.test.zone_id
#   # レコード名
#   name    = "api.test.com"
#   # レコードタイプ(Aレコード)
#   type    = "A"
#   # TTL(Time To Live)
#   ttl     = 300
#   # IPアドレスのリスト
#   records = ["76.76.21.21"]
# }

# Vercelプロジェクトのapexドメイン設定
# resource "vercel_project_domain" "apex_domain" {
#   # ドメイン名(apexドメイン)
#   domain               = "test.com"
#   # プロジェクトID
#   project_id           = vercel_project.test.id
#   # リダイレクト先
#   redirect             = "www.test.com"
#   # リダイレクトステータスコード
#   redirect_status_code = 307
#   # チームID
#   team_id              = var.team_id
# }

# Vercelプロジェクトのwwwドメイン設定
# resource "vercel_project_domain" "www_domain" {
#   domain     = "www.test.com"
#   project_id = vercel_project.test.id
#   redirect   = null
#   team_id    = var.team_id
# }

参考

最後に

間違っていることがあれば、コメントに書いていただけると幸いです。
よろしくお願いいたします。

GitHubで編集を提案

Discussion