Terraform でAWS 上にHA 構成のCData Sync を構築する

by 宇佐美格 | February 5, 2026

カバー画像

本記事では、Terraform を使って AWS 上にスケーラブルな CData Sync 環境を構築する方法を解説します。

Terraform 設定ファイル

本記事で使用したTerraform の設定ファイルは以下からダウンロードできます。

https://cdatajbuilds.s3.ap-northeast-1.amazonaws.com/Terraform/sync-ha-configuration-terraform.zip

アーキテクチャ概要

今回構築するアーキテクチャの全体像です。

アーキテクチャ

主要コンポーネント

コンポーネント

役割

Application Load Balancer

HTTPS(443)でのトラフィック分散

EC2 インスタンス(複数台)

CData Sync アプリケーション(ポート 8181)

RDS MySQL(Multi-AZ)

アプリケーションデータベース

EFS

EC2 インスタンス間の共有ストレージ

S3

セットアップファイルの保管

Route 53

DNS 管理

ACM

SSL/TLS 証明書

HA 構成のポイント

CData Sync を HA 構成で動かすには、複数インスタンス間で以下を共有する必要があります。

  1. アプリケーション DB → RDS MySQL で共有

  2. 設定ファイル・ジョブデータ → EFS で共有

事前準備

1. AWS CLI & Terraform のインストール

今回は、EC2 上に Amazon Linux 2023 のインスタンスを立ち上げて Terraform をインストールします。Amazon Linux 2023 ではAWS CLI が予めインストールされているため個別のインストール対応は不要です。ローカルマシンなどからTerraform を実行する場合はAWS のヘルプページなどを参考の上、AWS CLI を別途インストールください。

# Terraform のインストール
sudo yum install -y yum-utils shadow-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo
sudo yum -y install terraform

# バージョン確認
terraform version

また、Terraform で各種 AWS リソースを作成するために、EC2 に以下のポリシーが付与された IAM ロールをアタッチします。

2. Route 53 でのドメイン作成

Route 53 でホストゾーン (ドメイン) を作成します。今回は新たにドメインを作成しホストゾーンを作成しますAWS コンソールで Route53 のページからドメイン名を入力し作成します。

ドメインの登録

3. ACM での SSL 証明書発行

ALB で HTTPS を使用するため、ACM で SSL 証明書を発行します。

  1. AWS コンソールで Certificate Manager証明書をリクエスト

    証明書をリクエスト

  2. 「パブリック証明書をリクエスト」を選択

    パブリック証明書をリクエスト

  3. ドメイン名にワイルドカード証明書を入力し(例: *.example.com)、検証方法は「DNS 検証」を選択

    パブリック証明書作成

  4. Route 53 で DNS レコードを作成して検証を完了

  5. 発行された証明書の ARN をメモ(terraform.tfvars で使用)

    ACM ARN

4. EC2 キーペアの作成

EC2 インスタンスへの SSH アクセス用にキーペアを作成します。

# キーペアの作成
aws ec2 create-key-pair \
  --key-name cdata-sync-key \
  --query 'KeyMaterial' \
  --output text > cdata-sync-key.pem

または、AWS コンソールの EC2 → キーペア から作成することもできます。作成できたらキーペア名をメモします(terraform.tfvars で使用)

5. CData Sync のダウンロード

CData Sync の Linux 向けビルドをダウンロードし、セットアップアーカイブを準備します。

  1. CData Sync ダウンロードページ からクロスプラットフォーム版(tar.gz)をダウンロード

  2. ダウンロードしたファイルを Terraform 作業ディレクトリに CDataSync.tar.gz として配置します

Terraform コード解説

1. ネットワーク・セキュリティ構成

VPC、サブネット、セキュリティグループは標準的な構成です。ポイントだけ押さえておきます。

セキュリティグループの構成

SG

許可ポート

許可元

ALB SG

443 (HTTPS)

0.0.0.0/0

EC2 SG

8181 (App)

ALB SG のみ

RDS SG

3306 (MySQL)

EC2 SG のみ

EFS SG

2049 (NFS)

EC2 SG のみ

EC2 インスタンスはパブリック IP を持ちますが、セキュリティグループで ALB からのトラフィックのみに制限しています。

Note: 今回は簡単のため EC2 をパブリックサブネットに配置していますが、セキュリティ要件に応じてプライベートサブネットへの配置も検討してください。その場合は NAT ゲートウェイ(インターネットアクセス用)や VPC エンドポイント(S3、EFS、SSM など)の設定が必要になります。

2. EFS(共有ストレージ)

複数の EC2 インスタンス間で CData Sync の設定やジョブデータを共有するために EFS を使用します。

resource "aws_efs_file_system" "shared" {
  creation_token = "${var.project_name}-efs"
  encrypted      = true
  tags = {
    Name = "${var.project_name}-efs"
  }
}

resource "aws_efs_mount_target" "shared" {
  count           = length(aws_subnet.public)
  file_system_id  = aws_efs_file_system.shared.id
  subnet_id       = aws_subnet.public[count.index].id
  security_groups = [aws_security_group.efs_sg.id]
}

各 AZ にマウントターゲットを作成することで、どの EC2 インスタンスからも EFS にアクセスできます。

3. Application Load Balancer

resource "aws_lb" "app_alb" {
  name               = "${var.project_name}-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb_sg.id]
  subnets            = [for subnet in aws_subnet.public : subnet.id]
}

resource "aws_lb_target_group" "app_tg_main" {
  name        = "${var.project_name}-tg-main"
  port        = local.app_port
  protocol    = "HTTP"
  vpc_id      = aws_vpc.main.id
  target_type = "instance"

  health_check {
    enabled             = true
    interval            = 30
    path                = var.health_check_path  # /login.rst
    protocol            = "HTTP"
    timeout             = 5
    healthy_threshold   = 2
    unhealthy_threshold = 2
  }

  # ★ セッション維持のためスティッキーセッションを有効化
  stickiness {
    type            = "lb_cookie"
    cookie_duration = 3600
    enabled         = true
  }
}

スティッキーセッション: CData Sync はセッション状態を持つため、同じユーザーからのリクエストを同一インスタンスにルーティングします。

4. 個別インスタンスへのルーティング

デバッグや特定インスタンスへの直接アクセス用に、ホストヘッダーベースのルーティングを設定します。

# 個別ターゲットグループ(インスタンスごと)
resource "aws_lb_target_group" "app_tg_individual" {
  count       = var.instance_num
  name        = "${var.project_name}-tg-${count.index + 1}"
  port        = local.app_port
  protocol    = "HTTP"
  vpc_id      = aws_vpc.main.id
  target_type = "instance"
}

# ホストヘッダーベースのルーティングルール
resource "aws_lb_listener_rule" "instance_routing" {
  count        = var.instance_num
  listener_arn = aws_lb_listener.https_listener.arn
  priority     = 100 + count.index

  action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.app_tg_individual[count.index].arn
  }

  condition {
    host_header {
      values = ["${local.instance_subdomains[count.index]}.${var.domain_name}"]
    }
  }
}

これにより、以下のような URL でアクセスできます。

  • https://sync.example.com → 負荷分散(全インスタンス)

  • https://sync-1.example.com → インスタンス 1 のみ

  • https://sync-2.example.com → インスタンス 2 のみ

5. EC2 インスタンスと User Data

User Data で自動セットアップを行います。CData Sync 固有のアプリケーション設定はここに集約されています。

resource "aws_instance" "app_ec2" {
  count                  = var.instance_num
  ami                    = var.app_ami_id != null ? var.app_ami_id : data.aws_ami.ubuntu.id
  instance_type          = var.ec2_instance_type
  key_name               = var.ec2_key_name
  iam_instance_profile   = aws_iam_instance_profile.ec2_profile.name
  vpc_security_group_ids = [aws_security_group.ec2_sg.id]
  subnet_id              = aws_subnet.public[count.index % length(aws_subnet.public)].id
  
  user_data = <<-EOF
              #!/bin/bash
              set -e
              
              # Log output
              exec > >(tee /var/log/user-data.log)
              exec 2>&1
              
              echo "=== Starting CData Sync setup ==="
              echo "Timestamp: $(date)"
              
              # Install required packages
              echo "Installing required packages..."
              apt-get update -y
              apt-get install -y \
                nfs-common \
                unzip \
                curl
              
              # Install AWS CLI v2 (recommended for Ubuntu)
              echo "Installing AWS CLI v2..."
              if ! command -v aws &> /dev/null; then
                cd /tmp
                curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
                unzip -q awscliv2.zip
                ./aws/install
                rm -rf awscliv2.zip aws
                echo "AWS CLI installed: $(aws --version)"
              else
                echo "AWS CLI already installed: $(aws --version)"
              fi
              
              # Mount EFS
              echo "Mounting EFS..."
              mkdir -p ${var.efs_mount_point}
              mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 \
                ${aws_efs_file_system.shared.dns_name}:/ ${var.efs_mount_point}
              
              # Add to fstab for persistence
              echo "${aws_efs_file_system.shared.dns_name}:/ ${var.efs_mount_point} nfs4 nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 0 0" >> /etc/fstab
              
              # Create install directory
              echo "Creating install directory..."
              mkdir -p ${var.install_directory}
              cd ${var.install_directory}
              
              # Download setup archive from S3
              echo "Downloading CData Sync archive from S3..."
              aws s3 cp "s3://${aws_s3_bucket.setup_files.id}/${local.setup_script_key}" .
              
              # Extract archive
              echo "Extracting archive..."
              tar -xzf "${var.setup_archive_name}"
              
              # Execute service.sh
              echo "Executing service.sh..."
              if [ -f "service.sh" ]; then
                bash service.sh
              else
                echo "Error: service.sh not found"
                exit 1
              fi
              
              # Create sync directory on EFS after service.sh (cdatasync user should be created)
              echo "Creating sync directory on EFS..."
              mkdir -p ${var.efs_mount_point}/${var.efs_sync_directory}
              
              # Generate properties file
              echo "Generating sync.properties..."
              $(find ${var.install_directory}/jre/ -name java) -jar ${var.install_directory}/sync.jar -GenerateProperties
              
              # Configure RDS connection
              echo "Configuring RDS connection..."
              sed -i "s|^cdata.app.db=.*|cdata.app.db=jdbc:cdata:mysql:server=${aws_db_instance.default_rds.address};port=${aws_db_instance.default_rds.port};database=${var.rds_db_name};user=${var.rds_username};password=${var.rds_password}|" \
                ${var.install_directory}/sync.properties
              
              # Configure EFS directory (point to sync subdirectory)
              echo "Configuring EFS directory..."
              sed -i "s|^cdata.app.directory=.*|cdata.app.directory=${var.efs_mount_point}/${var.efs_sync_directory}|" \
                ${var.install_directory}/sync.properties

              # Change ownership to cdatasync user (created by service.sh)
              echo "Changing ownership of sync directory..."
              if id "cdatasync" &>/dev/null; then
                chown -R cdatasync:cdatasync ${var.efs_mount_point}/${var.efs_sync_directory}
                chmod 755 ${var.efs_mount_point}/${var.efs_sync_directory}
                echo "Ownership changed to cdatasync:cdatasync"
              else
                echo "Error: cdatasync user not found, creating..."
                exit 1
              fi
              
              # Enable and start service
              echo "Enabling and starting cdatasync service..."
              systemctl enable cdatasync
              systemctl start cdatasync
              
              echo "=== CData Sync setup completed successfully ==="
              echo "Timestamp: $(date)"
              EOF
  
  tags = {
    Name = "${var.project_name}-ec2-${count.index + 1}"
  }
  
  depends_on = [
    aws_s3_object.setup_archive,
    aws_efs_mount_target.shared
  ]
}

User Data のポイント

設定項目

説明

EFS マウント

/mnt/efs に共有ストレージをマウント

cdata.app.db

RDS への JDBC 接続文字列を設定

cdata.app.directory

EFS 上のディレクトリを指定し、全インスタンスで設定を共有

sync.properties の 2 つの設定(cdata.app.dbcdata.app.directory)が HA 構成に必須の設定値となります。詳細はヘルプページのクラスターのインストールと設定をご参照ください。

6. RDS MySQL

resource "aws_db_instance" "default_rds" {
  identifier             = "${var.project_name}-rds-db"
  allocated_storage      = var.rds_allocated_storage
  engine                 = var.rds_engine
  engine_version         = var.rds_engine_version
  instance_class         = var.rds_instance_class
  db_name                = var.rds_db_name
  username               = var.rds_username
  password               = var.rds_password
  db_subnet_group_name   = aws_db_subnet_group.rds_subnet_group.name
  vpc_security_group_ids = [aws_security_group.rds_sg.id]
  skip_final_snapshot    = true
  multi_az               = var.rds_multi_az
  tags = {
    Name = "${var.project_name}-rds-db"
  }
}

RDS をプライベートサブネットに配置し、EC2 からのみアクセス可能にしています。

変数設定(terraform.tfvars)

zip ファイルのterraform.tfvars.example terraform.tfvars にリネームの上、環境に合わせて各変数を修正します。

# Required variables
## Network
vpc_cidr             = "10.200.0.0/16"
public_subnet_cidrs  = ["10.200.1.0/24", "10.200.2.0/24"]
private_subnet_cidrs = ["10.200.101.0/24", "10.200.102.0/24"]

## Domain & ACM
domain_name          = "example.com"
common_subdomain     = "sync"
acm_certificate_arn  = "arn:aws:acm:ap-northeast-1:****:certificate/***"

## RDS
rds_password         = "YourSecurePassword123!"

## EC2
instance_num         = 2
ec2_key_name         = "examplekey"

# CData Sync setup configuration
setup_archive_path = "./CDataSync.tar.gz"  # Local path to your CData Sync tar.gz file
setup_archive_name = "CDataSync.tar.gz"

# Optional: Override defaults

# project_name       = "cdata-sync"
# aws_region         = "ap-northeast-1"
# ec2_instance_type  = "t3.large"
# rds_username       = "adminuser"
# rds_db_name        = "cdatasync"

## AMI ID (optional - defaults to latest Ubuntu 24.04 LTS)
# app_ami_id = "ami-0d52744d6551d851e"  # Uncomment to use specific AMI

デプロイ手順

# 1. 初期化
terraform init

# 2. プランを確認
terraform plan

# 3. デプロイ実行
terraform apply

デプロイ完了後、以下のような出力が表示されます。

app_main_url = "https://sync.example.com"
app_individual_urls = [
  "https://sync-1.example.com",
  "https://sync-2.example.com"
]
rds_endpoint = "cdata-sync-rds-db.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com:3306"

クラスタリング有効化

メイン URL (https://sync.example.com) にアクセスし、管理者ユーザーを作成後ログイン、ライセンスのアクティベート後、設定ページ内の[高度な設定] -> [追加設定] より[クラスターモードを許可]を有効化することでクラスタリングを有効化します。以上で設定は完了となります。

クラスタリング有効化

まとめ

Terraform を使って AWS 上に HA 構成の CData Sync をデプロイしました。この構成をベースに、Auto Scaling の追加や CloudWatch アラームの設定など、さらなる拡張も可能です。CData Sync は 30 日間の無償トライアルが可能ですので、ぜひお試しください! https://jp.cdata.com/sync/trial