Epic Games の Lore サーバーを AWS の Fargate + S3 + DynamoDB に Terraform でデプロイしてみた

Epic Games の Lore サーバーを AWS の Fargate + S3 + DynamoDB に Terraform でデプロイしてみた

Epic Games の VCS Lore のサーバーを、ECS Fargate と S3、DynamoDB を使ってフルマネージドに近い構成で AWS に立ててみました。Terraform で構築し、ローカルの lore クライアントから実際に push できるところまで確認します。
2026.07.12

はじめに

Epic Games のバージョン管理システム Lore は、サーバー (loreserver) をセルフホストできます。ストレージのバックエンドとして、ローカルディスクのほかに AWS の S3 と DynamoDB を選べます。本記事では、この loreserver を AWS 上にデプロイし、ローカルの lore クライアントから実際に使えるところまでを確認します。

構成のねらいは、できるだけマネージドサービスに任せることです。イミュータブルなデータを S3、可変な状態を DynamoDB に置けば、ストレージはサーバーレスになります。残る loreserver の実行を ECS Fargate に任せれば、EC2 を持たずに済みます。

loreserver は S3 と DynamoDB のバックエンドで問題なく動き、Fargate に載せてローカルから push できました。Lore 固有の依存は S3 と DynamoDB だけで、あとは Fargate 一般の構成です。ただし事前に作るべき DynamoDB テーブルのスキーマと、タスクロールに必要な権限にコツがあります。

Lore とは

Lore とは、Epic Games が 2026 年 6 月に公開したオープンソースのバージョン管理システムです。コードと大容量バイナリが混在するプロジェクト、特にゲームやエンタメ制作を主な対象としています。サーバーをセルフホストでき、ストレージのバックエンドに AWS の S3 と DynamoDB を選べます。

検証環境

  • リージョン: ap-northeast-1 (東京)
  • Terraform: 1.15
  • Docker (buildx): イメージのビルドに使用
  • 認証: aws-vault の profile を使用

対象読者

  • Lore を自チームでセルフホストしたいクラウドエンジニア
  • ゲーム開発やエンタメ制作で Lore の採用を検討していて、運用イメージをつかみたい方

参考

構成

全体の構成は次の通りです。クライアントは Network Load Balancer 経由で Fargate 上の loreserver に接続し、loreserver が S3 と DynamoDB を読み書きします。

  • イミュータブルストアは S3、ミュータブルストアとロックストアは DynamoDB に置きます。どちらもサーバーレスで、容量を気にせず従量課金で使えます。
  • loreserver の実行は ECS Fargate にします。EC2 を持たず、タスクの常駐やスケールを AWS に任せます。
  • クライアントとの通信は gRPC over TCP にします。Lore は QUIC over UDP も使えますが、TCP だけで clone や push を完結できるため、ロードバランサを単純にできます。
  • ロードバランサは Network Load Balancer の TCP リスナーにします。

前提となる Lore の仕様

デプロイの前に、loreserver の AWS バックエンドについて押さえておくべき点があります。

loreserver は起動時に、設定された S3 バケットと DynamoDB テーブルの存在を確認します。存在しないとエラーで停止します。つまり、バケットとテーブルは事前に作っておく必要があります。自動作成はされません。

DynamoDB のテーブルは 4 つ必要で、それぞれキースキーマが決まっています。属性型は B がバイナリ、S が文字列です。

  • fragments: パーティションキー hash (B) 、ソートキー repository_context (B)
  • metadata: パーティションキー hash (B)
  • mutable: パーティションキー repository_id (B) 、ソートキー key (B)
  • locks: パーティションキー hash (B) 、ソートキー repositoryBranch (B) 、および GSI 3 つ

locks テーブルの GSI は次の 3 つで、いずれも Projection は ALL です。

  • owner-repo-branch: パーティションキー ownerId (S) 、ソートキー repositoryBranch (B)
  • repo-branch: パーティションキー repository (B) 、ソートキー branch (B)
  • repo-branch-description: パーティションキー repositoryBranch (B) 、ソートキー description (S)

これらのスキーマは Lore のソースコード (lore-aws/src/store) から確認したものです。

手順 1: ストレージを Terraform で作る

まず S3 バケットと DynamoDB の 4 テーブルを作ります。ここが Lore 固有の部分です。DynamoDB は課金を抑えるためオンデマンド (PAY_PER_REQUEST) にします。

locks テーブルは GSI が参照する属性も attribute として定義する必要があります。Terraform では次のように書きます (抜粋) 。

storage.tf
resource "aws_dynamodb_table" "locks" {
  name         = "lorec-locks"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "hash"
  range_key    = "repositoryBranch"

  attribute { name = "hash"             type = "B" }
  attribute { name = "repositoryBranch" type = "B" }
  attribute { name = "repository"       type = "B" }
  attribute { name = "branch"           type = "B" }
  attribute { name = "ownerId"          type = "S" }
  attribute { name = "description"      type = "S" }

  global_secondary_index {
    name            = "owner-repo-branch"
    hash_key        = "ownerId"
    range_key       = "repositoryBranch"
    projection_type = "ALL"
  }
  # repo-branch, repo-branch-description も同様に定義する
}

fragments と metadata と mutable のテーブルは、前述のスキーマの通りシンプルに定義します。

手順 2: IAM タスクロール

loreserver が S3 と DynamoDB にアクセスするためのタスクロールを作ります。注意すべき点として、CRUD の権限 (GetItem や PutItem など) だけでは足りません。loreserver は起動時にテーブルの存在を DescribeTable で確認するため、dynamodb:DescribeTable が必要です。これが抜けているとコンテナが起動直後にクラッシュします (詳しくは後述) 。

タスクロールに与える DynamoDB のアクションは次のようにします。

iam.tf
actions = [
  "dynamodb:DescribeTable",
  "dynamodb:GetItem",
  "dynamodb:PutItem",
  "dynamodb:UpdateItem",
  "dynamodb:DeleteItem",
  "dynamodb:Query",
  "dynamodb:BatchGetItem",
  "dynamodb:BatchWriteItem",
  "dynamodb:ConditionCheckItem",
]

対象リソースは 4 テーブルの ARN と、locks テーブルの index/* です。S3 は対象バケットに対して GetObject や PutObject、ListBucket を与えます。

手順 3: コンテナイメージのビルドと ECR への push

loreserver のコンテナイメージは、公式リポジトリの Dockerfile からビルドします。

1 つ目の注意点は CPU アーキテクチャです。Fargate では linux/amd64 のイメージを使います。Lore の arm64 イメージは Graviton3 の SVE 命令を前提としており、Apple Silicon や Fargate ARM64 (Graviton2) では動きません。Apple Silicon 上で amd64 をエミュレーションビルドすると、Rust のコンパイルに数分から十数分かかりますが、完了はします。

2 つ目の注意点は設定の渡し方です。公式イメージは /etc/lore/config から設定を読みます。ここに、AWS バックエンドを指す local.toml を焼き込んだオーバーレイイメージを作ります。

Dockerfile
FROM lore-server:base-amd64
COPY local.toml /etc/lore/config/local.toml

local.toml は次のようにします。実 AWS を使うので endpoint は指定せず、s3_force_path_style は false にします。バケット名とテーブル名は手順 1 で作ったものに合わせます。

local.toml
[immutable_store]
mode = "aws"
[mutable_store]
mode = "aws"
[lock_store]
mode = "aws"

[plugins.aws.immutable_store]
s3_bucket = "lorec-store-<アカウント ID>"
s3_region = "ap-northeast-1"
s3_force_path_style = false
dynamodb_fragments_table = "lorec-fragments"
dynamodb_metadata_table = "lorec-metadata"
dynamodb_region = "ap-northeast-1"

[plugins.aws.mutable_store]
dynamodb_table = "lorec-mutable"
dynamodb_region = "ap-northeast-1"

[plugins.aws.lock_store]
dynamodb_table = "lorec-locks"
dynamodb_region = "ap-northeast-1"

ビルドしたイメージを ECR に push します。

手順 4: ネットワークと Fargate

Network Load Balancer を作り、TCP リスナー 41337 を Fargate サービスのターゲットグループに向けます。ターゲットグループのヘルスチェックは、loreserver の HTTP エンドポイント 41339 の /health_check に向けます。

セキュリティグループは 2 段にします。NLB 用のセキュリティグループで自分の IP からの 41337 だけを許可し、タスク用のセキュリティグループで NLB のセキュリティグループからのみ受けます。これで、公開しつつアクセス元を自分に限定できます。

Fargate のタスク定義では、アーキテクチャを X86_64 に指定し、イメージは ECR のもの、ポートは 41337 と 41339、タスクロールは手順 2 のもの、ログは awslogs にします。サービスの希望タスク数は 1 とし、NLB のターゲットグループに紐付けます。

lore01

lore02

手順 5: デプロイ

Terraform を apply し、S3 と DynamoDB、ECR、NLB、Fargate を作ります。イメージを ECR に push した後、Fargate のサービスがタスクを起動し、NLB のターゲットが healthy になれば準備完了です。

lore03

つまずき: タスクが起動直後にクラッシュする

デプロイして最初に当たったのがこれでした。Fargate のタスクが起動直後に終了し、繰り返し再起動します。ECS サービスの実行中タスク数は 0 のまま、NLB のターゲットは initial から進みません。

ECS のイベントには詳細が出ません。原因はコンテナのログにあります。CloudWatch Logs のロググループ /ecs/lorec-server を見ると、次のエラーが出ていました。

Plugin 'aws' initialization failed: Failed to create DynamoDB client:
AccessDeniedException: User: .../lorec-task/... is not authorized to
perform: dynamodb:DescribeTable on resource: .../table/lorec-fragments
because no identity-based policy allows the dynamodb:DescribeTable action

loreserver は起動時に DescribeTable でテーブルの存在を確認します。タスクロールに CRUD の権限しか与えていなかったため、この確認で権限エラーになりクラッシュしていました。手順 2 の通り dynamodb:DescribeTable を足すと、正常に起動しました。

Fargate のタスクがすぐ終了するときは、ECS のイベントではなくコンテナの CloudWatch Logs を見ます。loreserver の AWS バックエンドは、CRUD に加えて起動時の存在確認に DescribeTable を要します。

lore06

疎通確認

タスクが起動し、NLB のターゲットが healthy になったら、ローカルの lore クライアントから接続します。NLB の DNS 名に対して grpc:// で接続します。

lore repository create grpc://<NLB の DNS>:41337/awsdemo
lore stage asset.bin
lore commit --identity <名前> "v1 on fargate"
lore push
lore clone grpc://<NLB の DNS>:41337/awsdemo ./cloned

create から push、clone まですべて成功し、clone したファイルの内容が元と一致しました。ローカルの lore クライアントが、NLB 経由で Fargate 上の loreserver に到達し、往復できています。

データが実際に AWS に入ったかについても確認します。小さなファイル 1 つを含むリポジトリで、次のようになりました。

lore04
S3 バケット: 11 オブジェクト。キーは BLAKE3 ハッシュで、コンテンツアドレス方式で格納されている

lore05
DynamoDB: fragments 11 件、metadata 11 件、mutable 5 件、locks 0 件

これはローカル環境で確認したときと同じ件数で、Fargate 上の loreserver が実 S3 と DynamoDB を正しく使っていることの裏づけになります。

まとめ

loreserver を AWS の Fargate + S3 + DynamoDB に Terraform でデプロイし、ローカルのクライアントから push できるところまで確認しました。

やってみて分かったのは、Lore 固有の依存は S3 と DynamoDB だけだということです。あとは Fargate に載せるための一般的な構成です。ストレージがサーバーレスなので、loreserver の実行を Fargate にすれば、状態を持たない実行環境になり、運用が楽になります。

一方でコツもありました。DynamoDB のテーブルは決まったスキーマで事前に作る必要があること、タスクロールに dynamodb:DescribeTable が要ること、Fargate では amd64 イメージが必須なことです。 特に DescribeTable の権限不足は、起動直後のクラッシュという分かりにくい形で現れます。

本記事の構成は、アクセス元を自分の IP に限定した検証用のものです。認証を有効にする、プライベートサブネットに置く、といった本番向けの作り込みは別途必要となることに注意してください。

付録: 実装の全文

本記事で使った Terraform とイメージ定義の全文です。allowed_cidr は自分のグローバル IP に、local.tomls3_bucket は自分のアカウント ID に合わせて置き換えてください。

Terraform 一式
providers.tf
terraform {
  required_version = ">= 1.5"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 5.40"
    }
  }
}

provider "aws" {
  region = var.region

  default_tags {
    tags = {
      Project   = "blog-lore-article-c"
      ManagedBy = "terraform"
    }
  }
}

data "aws_caller_identity" "current" {}
variables.tf
variable "region" {
  description = "デプロイ先リージョン"
  type        = string
  default     = "ap-northeast-1"
}

variable "name_prefix" {
  description = "リソース名の接頭辞"
  type        = string
  default     = "lorec"
}

variable "allowed_cidr" {
  description = "NLB へのアクセスを許可するソース CIDR (自分のグローバル IP)"
  type        = string
  # 実行時に -var で上書きするか、ここを自分の IP に書き換える
  default     = "203.0.113.10/32"
}

variable "image_tag" {
  description = "loreserver コンテナイメージのタグ"
  type        = string
  default     = "v1"
}

variable "task_cpu" {
  description = "Fargate タスクの CPU ユニット"
  type        = number
  default     = 512
}

variable "task_memory" {
  description = "Fargate タスクのメモリ (MiB)"
  type        = number
  default     = 1024
}
storage.tf
# イミュータブルなデータ用の S3 バケット
resource "aws_s3_bucket" "store" {
  bucket        = "${var.name_prefix}-store-${data.aws_caller_identity.current.account_id}"
  force_destroy = true
}

resource "aws_s3_bucket_public_access_block" "store" {
  bucket                  = aws_s3_bucket.store.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

# fragments テーブル
resource "aws_dynamodb_table" "fragments" {
  name         = "${var.name_prefix}-fragments"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "hash"
  range_key    = "repository_context"

  attribute {
    name = "hash"
    type = "B"
  }
  attribute {
    name = "repository_context"
    type = "B"
  }
}

# metadata テーブル
resource "aws_dynamodb_table" "metadata" {
  name         = "${var.name_prefix}-metadata"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "hash"

  attribute {
    name = "hash"
    type = "B"
  }
}

# mutable テーブル
resource "aws_dynamodb_table" "mutable" {
  name         = "${var.name_prefix}-mutable"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "repository_id"
  range_key    = "key"

  attribute {
    name = "repository_id"
    type = "B"
  }
  attribute {
    name = "key"
    type = "B"
  }
}

# locks テーブル (GSI 3 個)
resource "aws_dynamodb_table" "locks" {
  name         = "${var.name_prefix}-locks"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "hash"
  range_key    = "repositoryBranch"

  attribute {
    name = "hash"
    type = "B"
  }
  attribute {
    name = "repositoryBranch"
    type = "B"
  }
  attribute {
    name = "repository"
    type = "B"
  }
  attribute {
    name = "branch"
    type = "B"
  }
  attribute {
    name = "ownerId"
    type = "S"
  }
  attribute {
    name = "description"
    type = "S"
  }

  global_secondary_index {
    name            = "owner-repo-branch"
    hash_key        = "ownerId"
    range_key       = "repositoryBranch"
    projection_type = "ALL"
  }
  global_secondary_index {
    name            = "repo-branch"
    hash_key        = "repository"
    range_key       = "branch"
    projection_type = "ALL"
  }
  global_secondary_index {
    name            = "repo-branch-description"
    hash_key        = "repositoryBranch"
    range_key       = "description"
    projection_type = "ALL"
  }
}
iam.tf
data "aws_iam_policy_document" "ecs_assume" {
  statement {
    actions = ["sts:AssumeRole"]
    principals {
      type        = "Service"
      identifiers = ["ecs-tasks.amazonaws.com"]
    }
  }
}

# タスク実行ロール: ECR からの pull と CloudWatch Logs への書き込み
resource "aws_iam_role" "execution" {
  name               = "${var.name_prefix}-exec"
  assume_role_policy = data.aws_iam_policy_document.ecs_assume.json
}

resource "aws_iam_role_policy_attachment" "execution" {
  role       = aws_iam_role.execution.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}

# タスクロール: loreserver が S3 と DynamoDB にアクセスするための権限
resource "aws_iam_role" "task" {
  name               = "${var.name_prefix}-task"
  assume_role_policy = data.aws_iam_policy_document.ecs_assume.json
}

data "aws_iam_policy_document" "task" {
  statement {
    sid     = "S3"
    actions = ["s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:ListBucket"]
    resources = [
      aws_s3_bucket.store.arn,
      "${aws_s3_bucket.store.arn}/*",
    ]
  }
  statement {
    sid = "DynamoDB"
    actions = [
      "dynamodb:DescribeTable",
      "dynamodb:GetItem",
      "dynamodb:PutItem",
      "dynamodb:UpdateItem",
      "dynamodb:DeleteItem",
      "dynamodb:Query",
      "dynamodb:BatchGetItem",
      "dynamodb:BatchWriteItem",
      "dynamodb:ConditionCheckItem",
    ]
    resources = [
      aws_dynamodb_table.fragments.arn,
      aws_dynamodb_table.metadata.arn,
      aws_dynamodb_table.mutable.arn,
      aws_dynamodb_table.locks.arn,
      "${aws_dynamodb_table.locks.arn}/index/*",
    ]
  }
}

resource "aws_iam_role_policy" "task" {
  name   = "${var.name_prefix}-task-policy"
  role   = aws_iam_role.task.id
  policy = data.aws_iam_policy_document.task.json
}
network.tf
data "aws_vpc" "default" {
  default = true
}

data "aws_subnets" "default" {
  filter {
    name   = "vpc-id"
    values = [data.aws_vpc.default.id]
  }
}

# NLB 用セキュリティグループ: 自分の IP からの 41337 / 41339 のみ許可
resource "aws_security_group" "nlb" {
  name        = "${var.name_prefix}-nlb"
  description = "Allow lore ports from the operator IP only"
  vpc_id      = data.aws_vpc.default.id

  ingress {
    description = "gRPC/QUIC"
    from_port   = 41337
    to_port     = 41337
    protocol    = "tcp"
    cidr_blocks = [var.allowed_cidr]
  }
  ingress {
    description = "HTTP health"
    from_port   = 41339
    to_port     = 41339
    protocol    = "tcp"
    cidr_blocks = [var.allowed_cidr]
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

# Fargate タスク用セキュリティグループ: NLB からのみ受ける
resource "aws_security_group" "task" {
  name        = "${var.name_prefix}-task"
  description = "Allow lore ports from the NLB security group"
  vpc_id      = data.aws_vpc.default.id

  ingress {
    description     = "gRPC/QUIC from NLB"
    from_port       = 41337
    to_port         = 41337
    protocol        = "tcp"
    security_groups = [aws_security_group.nlb.id]
  }
  ingress {
    description     = "HTTP health from NLB"
    from_port       = 41339
    to_port         = 41339
    protocol        = "tcp"
    security_groups = [aws_security_group.nlb.id]
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_lb" "nlb" {
  name               = "${var.name_prefix}-nlb"
  internal           = false
  load_balancer_type = "network"
  security_groups    = [aws_security_group.nlb.id]
  subnets            = data.aws_subnets.default.ids
}

# gRPC/TCP のターゲットグループ (Fargate awsvpc なので target_type = ip)
resource "aws_lb_target_group" "grpc" {
  name        = "${var.name_prefix}-grpc"
  port        = 41337
  protocol    = "TCP"
  target_type = "ip"
  vpc_id      = data.aws_vpc.default.id

  health_check {
    protocol = "HTTP"
    port     = "41339"
    path     = "/health_check"
    interval = 30
  }
}

resource "aws_lb_listener" "grpc" {
  load_balancer_arn = aws_lb.nlb.arn
  port              = 41337
  protocol          = "TCP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.grpc.arn
  }
}
ecs.tf
resource "aws_ecr_repository" "lore" {
  name                 = "${var.name_prefix}-server"
  image_tag_mutability = "MUTABLE"
  force_delete         = true
}

resource "aws_cloudwatch_log_group" "lore" {
  name              = "/ecs/${var.name_prefix}-server"
  retention_in_days = 7
}

resource "aws_ecs_cluster" "lore" {
  name = "${var.name_prefix}-cluster"
}

resource "aws_ecs_task_definition" "lore" {
  family                   = "${var.name_prefix}-server"
  requires_compatibilities = ["FARGATE"]
  network_mode             = "awsvpc"
  cpu                      = var.task_cpu
  memory                   = var.task_memory
  execution_role_arn       = aws_iam_role.execution.arn
  task_role_arn            = aws_iam_role.task.arn

  runtime_platform {
    operating_system_family = "LINUX"
    cpu_architecture        = "X86_64"
  }

  container_definitions = jsonencode([
    {
      name      = "loreserver"
      image     = "${aws_ecr_repository.lore.repository_url}:${var.image_tag}"
      essential = true
      portMappings = [
        { containerPort = 41337, protocol = "tcp" },
        { containerPort = 41339, protocol = "tcp" },
      ]
      logConfiguration = {
        logDriver = "awslogs"
        options = {
          "awslogs-group"         = aws_cloudwatch_log_group.lore.name
          "awslogs-region"        = var.region
          "awslogs-stream-prefix" = "loreserver"
        }
      }
    }
  ])
}

resource "aws_ecs_service" "lore" {
  name            = "${var.name_prefix}-server"
  cluster         = aws_ecs_cluster.lore.id
  task_definition = aws_ecs_task_definition.lore.arn
  desired_count   = 1
  launch_type     = "FARGATE"

  network_configuration {
    subnets          = data.aws_subnets.default.ids
    security_groups  = [aws_security_group.task.id]
    assign_public_ip = true
  }

  load_balancer {
    target_group_arn = aws_lb_target_group.grpc.arn
    container_name   = "loreserver"
    container_port   = 41337
  }

  depends_on = [aws_lb_listener.grpc]
}
outputs.tf
output "nlb_dns" {
  description = "NLB の DNS 名。クライアントは grpc://<この値>:41337 で接続する"
  value       = aws_lb.nlb.dns_name
}

output "ecr_repository_url" {
  description = "loreserver イメージの push 先"
  value       = aws_ecr_repository.lore.repository_url
}

output "s3_bucket" {
  value = aws_s3_bucket.store.bucket
}

output "dynamodb_tables" {
  value = {
    fragments = aws_dynamodb_table.fragments.name
    metadata  = aws_dynamodb_table.metadata.name
    mutable   = aws_dynamodb_table.mutable.name
    locks     = aws_dynamodb_table.locks.name
  }
}

output "ecs_cluster" {
  value = aws_ecs_cluster.lore.name
}

output "ecs_service" {
  value = aws_ecs_service.lore.name
}
コンテナイメージ (Dockerfile と local.toml)

公式リポジトリの lore-server/Dockerfile から lore-server:base-amd64 をビルドしておき、それをベースに local.toml を焼き込みます。

Dockerfile
# 公式ビルド済みイメージ (lore-server:base-amd64) に、AWS バックエンド用の
# local.toml を焼き込むオーバーレイ。local.toml は /etc/lore/config に置かれ、
# LORE_ENV=docker の docker.toml より後に読まれて mode を aws に上書きする。
FROM lore-server:base-amd64
COPY local.toml /etc/lore/config/local.toml

s3_bucket は Terraform の出力 s3_bucket と同じ値にします。

local.toml
[immutable_store]
mode = "aws"

[mutable_store]
mode = "aws"

[lock_store]
mode = "aws"

[plugins.aws.immutable_store]
s3_bucket = "lorec-store-<アカウント ID>"
s3_region = "ap-northeast-1"
s3_force_path_style = false
dynamodb_fragments_table = "lorec-fragments"
dynamodb_metadata_table = "lorec-metadata"
dynamodb_region = "ap-northeast-1"
timeout_millis = 120000

[plugins.aws.mutable_store]
dynamodb_table = "lorec-mutable"
dynamodb_region = "ap-northeast-1"
timeout_millis = 120000

[plugins.aws.lock_store]
dynamodb_table = "lorec-locks"
dynamodb_region = "ap-northeast-1"
timeout_millis = 120000

ゲーム開発・運用環境の効率化を支援します

Classmethodの専門家による包括的なクラウド活用とデジタル化支援で、ゲーム開発の効率を最大化しましょう。AWSの導入から運用、最適化まで、最新技術と豊富な経験であらゆる課題を解決します。株式会社CAPCOM様、株式会社SNK様などの事例もご覧いただけます。

ゲーム業界のサービス詳細を見る

この記事をシェアする

関連記事