オンプレからAWS環境へのAppサーバ移行について

どうも、クラ本の黒田です。
今日は、オンプレからAWS環境へのAppサーバ移行について触れたいと思います。

📖 目次

  1. はじめに
  2. 移行アーキテクチャ概要
  3. 前提条件と準備
  4. Phase 1: AWS環境基盤構築
  5. Phase 2: MGN環境準備
  6. Phase 3: サーバレプリケーション
  7. Phase 4: ファイルシステム移行
  8. Phase 5: データベース移行
  9. Phase 6: アプリケーション統合
  10. 移行後の確認とテスト
  11. トラブルシューティング
  12. まとめ

🚀 はじめに

企業のDX推進において、オンプレミス環境からクラウド環境への移行は重要な戦略の一つです。本記事では、サーバをオンプレミス環境からAWS環境に移行する実践的な手順を解説します。

🎯 移行の目標

  • ゼロダウンタイム移行: サービス停止時間を最小限に抑制
  • データ整合性確保: アプリケーションデータとファイルの完全移行
  • パフォーマンス向上: AWS マネージドサービスの活用による性能改善
  • 運用効率化: クラウドネイティブな運用体制の確立

🏗️ 移行アーキテクチャ概要

システム構成図

file

移行フロー概要

file

✅ 前提条件と準備

システム要件

オンプレミス環境

  • OS: Linux (CentOS/RHEL/Ubuntu)
  • アプリケーション: 8.x以上
  • データベース: PostgreSQL (アプリ内蔵または外部)
  • ネットワーク: インターネット接続(MGNエージェント用)

AWS環境

  • VPC: プライベート・パブリックサブネット構成
  • セキュリティグループ: 適切なポート開放設定
  • IAM: 必要な権限を持つロール・ユーザー

事前準備項目

項目 詳細 確認事項
ネットワーク設計 VPC、サブネット、ルーティング セキュリティ要件との整合性
セキュリティ設計 セキュリティグループ、NACL 最小権限の原則に基づく設定
バックアップ計画 移行前のデータバックアップ データ損失リスクへの対策
ダウンタイム計画 メンテナンスウィンドウ設定 ビジネス影響の最小化

🔧 Phase 1: AWS環境基盤構築

Step 1-1: Aurora PostgreSQLの構築

# Aurora PostgreSQLクラスターの作成
aws rds create-db-cluster \
    --db-cluster-identifier App-aurora-cluster \
    --engine aurora-postgresql \
    --engine-version 13.7 \
    --master-username Appadmin \
    --master-user-password 'SecurePassword123!' \
    --vpc-security-group-ids sg-xxxxxxxxx \
    --db-subnet-group-name App-db-subnet-group \
    --backup-retention-period 7 \
    --preferred-backup-window "03:00-04:00" \
    --preferred-maintenance-window "sun:04:00-sun:05:00" \
    --deletion-protection \
    --storage-encrypted

# Aurora インスタンスの作成
aws rds create-db-instance \
    --db-instance-identifier App-aurora-writer \
    --db-instance-class db.r6g.large \
    --engine aurora-postgresql \
    --db-cluster-identifier App-aurora-cluster \
    --publicly-accessible false \
    --monitoring-interval 60 \
    --monitoring-role-arn arn:aws:iam::123456789012:role/rds-monitoring-role

Step 1-2: EFSの構築

# EFSファイルシステムの作成
aws efs create-file-system \
    --creation-token App-efs-$(date +%s) \
    --performance-mode generalPurpose \
    --throughput-mode provisioned \
    --provisioned-throughput-in-mibps 100 \
    --encrypted

# EFSマウントターゲットの作成
aws efs create-mount-target \
    --file-system-id fs-xxxxxxxxx \
    --subnet-id subnet-xxxxxxxxx \
    --security-groups sg-xxxxxxxxx

Step 1-3: 本番インスタンスのセットアップ

# 本番EC2インスタンスでEFSマウント
sudo yum install -y amazon-efs-utils

# マウントディレクトリ作成
sudo mkdir -p /opt/app/shared

# EFSをマウント
sudo mount -t efs -o tls fs-xxxxxxxxx:/ /opt/app/shared

# 永続化設定
echo "fs-xxxxxxxxx.efs.ap-northeast-1.amazonaws.com:/ /opt/app/shared efs tls,_netdev" | sudo tee -a /etc/fstab

# Appアプリケーションの初期セットアップ
sudo systemctl start app
sudo systemctl enable app

🔐 Phase 2: MGN環境準備

Step 2-1: IAMユーザーとポリシーの作成

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "mgn:*",
                "ec2:DescribeInstances",
                "ec2:DescribeImages",
                "ec2:DescribeSnapshots",
                "ec2:DescribeVolumes",
                "ec2:DetachVolume",
                "ec2:AttachVolume",
                "ec2:ModifyInstanceAttribute",
                "ec2:RunInstances",
                "ec2:StartInstances",
                "ec2:StopInstances",
                "ec2:TerminateInstances",
                "ec2:CreateImage",
                "ec2:CopyImage",
                "ec2:CreateSnapshot",
                "ec2:CreateTags",
                "ec2:DeleteTags",
                "iam:PassRole"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreateServiceLinkedRole"
            ],
            "Resource": "arn:aws:iam::*:role/aws-service-role/mgn.amazonaws.com/AWSServiceRoleForApplicationMigrationService"
        }
    ]
}
# IAMポリシー作成
aws iam create-policy \
    --policy-name AppMGNMigrationPolicy \
    --policy-document file://mgn-policy.json

# IAMユーザー作成
aws iam create-user \
    --user-name App-mgn-user

# ポリシーアタッチ
aws iam attach-user-policy \
    --user-name App-mgn-user \
    --policy-arn arn:aws:iam::123456789012:policy/AppMGNMigrationPolicy

# アクセスキー発行
aws iam create-access-key \
    --user-name App-mgn-user

Step 2-2: MGNサービスの初期化

# MGNサービス初期化
aws mgn initialize-service --region ap-northeast-1

# レプリケーション設定テンプレート作成
aws mgn create-replication-configuration-template \
    --associate-default-security-group true \
    --bandwidth-throttling 0 \
    --create-public-ip false \
    --data-plane-routing PRIVATE_IP \
    --default-large-staging-disk-type GP3 \
    --ebs-encryption DEFAULT \
    --replication-server-instance-type m5.large \
    --replication-servers-security-groups-i-ds sg-xxxxxxxxx \
    --staging-area-subnet-id subnet-xxxxxxxxx \
    --staging-area-tags Environment=Migration,Project=App \
    --use-dedicated-replication-server false

📡 Phase 3: サーバレプリケーション

Step 3-1: オンプレミスサーバでのMGNエージェントインストール

# オンプレミスサーバ側での作業

# MGNエージェントダウンロード
wget -O ./aws-replication-installer-init.py https://aws-application-migration-service-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/linux/aws-replication-installer-init.py

# インストーラーの実行
sudo python3 aws-replication-installer-init.py \
    --region ap-northeast-1 \
    --aws-access-key-id AKIAXXXXXXXXXXXXXXXX \
    --aws-secret-access-key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
    --no-prompt

# レプリケーション状況確認
sudo tail -f /var/log/aws-replication-agent.log

Step 3-2: レプリケーション設定と監視

# レプリケーション状況の確認
aws mgn describe-source-servers \
    --filters name=isArchived,values=false

# レプリケーション進捗の詳細確認
aws mgn describe-source-servers \
    --source-server-ids s-xxxxxxxxxxxxxxxxx \
    --query 'sourceServers[0].dataReplicationInfo'

# カットオーバー設定
aws mgn start-cutover \
    --source-server-ids s-xxxxxxxxxxxxxxxxx

Step 3-3: カットオーバー実行と確認

# カットオーバー状況確認
aws mgn describe-source-servers \
    --source-server-ids s-xxxxxxxxxxxxxxxxx \
    --query 'sourceServers[0].lifeCycle.state'

# カットオーバー完了後のインスタンス情報取得
CUTOVER_INSTANCE_ID=$(aws mgn describe-source-servers \
    --source-server-ids s-xxxxxxxxxxxxxxxxx \
    --query 'sourceServers[0].lifeCycle.elapsedReplicationDuration' \
    --output text)

# インスタンスへの接続確認
aws ec2 describe-instances \
    --instance-ids $CUTOVER_INSTANCE_ID \
    --query 'Reservations[0].Instances[0].State.Name'

📁 Phase 4: ファイルシステム移行

Step 4-1: カットオーバーインスタンスでのファイル準備

# カットオーバー完了済みインスタンスでの作業

# マウントディレクトリ作成
sudo mkdir -p /mnt/migration-temp

# Appホームディレクトリのアーカイブ作成
sudo tar -czf /mnt/migration-temp/App-home-backup.tar.gz /var/application-data/App/

# アプリケーションファイルのアーカイブ作成
sudo tar -czf /mnt/migration-temp/App-install-backup.tar.gz /opt/App/

# ログファイルのアーカイブ作成
sudo tar -czf /mnt/migration-temp/App-logs-backup.tar.gz /opt/App/logs/

# 設定ファイルのコピー
sudo cp -r /var/application-data/App/dbconfig.xml /mnt/migration-temp/
sudo cp -r /opt/App/conf/ /mnt/migration-temp/App-conf/

# ファイル権限とサイズの確認
ls -la /mnt/migration-temp/
du -sh /mnt/migration-temp/*

Step 4-2: 本番インスタンスでのEFS設定とファイル移行

# 本番インスタンスでの作業

# EFSマウントディレクトリ作成
sudo mkdir -p /mnt/efs-shared

# EFSマウント(すでに設定済みの場合はスキップ)
sudo mount -t efs -o tls fs-xxxxxxxxx:/ /mnt/efs-shared

# カットオーバーインスタンスからファイル転送
# SCPまたはrsyncを使用してファイル転送
scp -i ~/.ssh/migration-key.pem ec2-user@CUTOVER_INSTANCE_IP:/mnt/migration-temp/* /mnt/efs-shared/

# ファイルの展開と配置
cd /mnt/efs-shared/
sudo tar -xzf App-home-backup.tar.gz -C /opt/App/
sudo tar -xzf App-install-backup.tar.gz -C /
sudo tar -xzf App-logs-backup.tar.gz -C /opt/App/

# 設定ファイルの配置
sudo cp dbconfig.xml /var/application-data/App/
sudo cp -r App-conf/* /opt/App/conf/

# ファイル権限の修正
sudo chown -R App:App /var/application-data/App/
sudo chown -R App:App /opt/App/
sudo chmod -R 750 /var/application-data/App/

🗄️ Phase 5: データベース移行

Step 5-1: DMSレプリケーションインスタンスの作成

# DMSレプリケーションインスタンス作成
aws dms create-replication-instance \
    --replication-instance-identifier App-dms-replication \
    --replication-instance-class dms.t3.medium \
    --allocated-storage 50 \
    --vpc-security-group-ids sg-xxxxxxxxx \
    --replication-subnet-group-identifier App-dms-subnet-group \
    --publicly-accessible false \
    --multi-az false

# レプリケーションインスタンス状況確認
aws dms describe-replication-instances \
    --replication-instance-identifier App-dms-replication

Step 5-2: DMSエンドポイント設定

# ソースエンドポイント(カットオーバーインスタンス内PostgreSQL)作成
aws dms create-endpoint \
    --endpoint-identifier App-source-postgres \
    --endpoint-type source \
    --engine-name postgres \
    --server-name CUTOVER_INSTANCE_PRIVATE_IP \
    --port 5432 \
    --database-name Appdb \
    --username App \
    --password 'SourceDBPassword123!'

# ターゲットエンドポイント(Aurora PostgreSQL)作成
aws dms create-endpoint \
    --endpoint-identifier App-target-aurora \
    --endpoint-type target \
    --engine-name aurora-postgresql \
    --server-name App-aurora-cluster.cluster-xxxxxxxxx.ap-northeast-1.rds.amazonaws.com \
    --port 5432 \
    --database-name Appdb \
    --username Appadmin \
    --password 'SecurePassword123!'

# エンドポイント接続テスト
aws dms test-connection \
    --replication-instance-arn arn:aws:dms:ap-northeast-1:123456789012:rep:App-dms-replication \
    --endpoint-arn arn:aws:dms:ap-northeast-1:123456789012:endpoint:App-source-postgres

aws dms test-connection \
    --replication-instance-arn arn:aws:dms:ap-northeast-1:123456789012:rep:App-dms-replication \
    --endpoint-arn arn:aws:dms:ap-northeast-1:123456789012:endpoint:App-target-aurora

Step 5-3: DMSタスク作成と実行

{
    "rules": [
        {
            "rule-type": "selection",
            "rule-id": "1",
            "rule-name": "1",
            "object-locator": {
                "schema-name": "public",
                "table-name": "%"
            },
            "rule-action": "include"
        },
        {
            "rule-type": "transformation",
            "rule-id": "2",
            "rule-name": "2",
            "rule-target": "schema",
            "object-locator": {
                "schema-name": "public"
            },
            "rule-action": "rename",
            "value": "public"
        }
    ]
}
# DMSタスク作成
aws dms create-replication-task \
    --replication-task-identifier App-full-load-task \
    --source-endpoint-arn arn:aws:dms:ap-northeast-1:123456789012:endpoint:App-source-postgres \
    --target-endpoint-arn arn:aws:dms:ap-northeast-1:123456789012:endpoint:App-target-aurora \
    --replication-instance-arn arn:aws:dms:ap-northeast-1:123456789012:rep:App-dms-replication \
    --migration-type full-load \
    --table-mappings file://table-mappings.json

# レプリケーションタスク開始
aws dms start-replication-task \
    --replication-task-arn arn:aws:dms:ap-northeast-1:123456789012:task:App-full-load-task \
    --start-replication-task-type start-replication

# タスク進捗確認
aws dms describe-replication-tasks \
    --replication-task-arns arn:aws:dms:ap-northeast-1:123456789012:task:App-full-load-task

🔗 Phase 6: アプリケーション統合

Step 6-1: データベース接続設定変更

<!-- /var/application-data/App/dbconfig.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<App-database-config>
  <name>defaultDS</name>
  <delegator-name>default</delegator-name>
  <database-type>postgres72</database-type>
  <schema-name>public</schema-name>
  <jdbc-datasource>
    <url>jdbc:postgresql://App-aurora-cluster.cluster-xxxxxxxxx.ap-northeast-1.rds.amazonaws.com:5432/Appdb</url>
    <driver-class>org.postgresql.Driver</driver-class>
    <username>Appadmin</username>
    <password>SecurePassword123!</password>
    <pool-min-size>20</pool-min-size>
    <pool-max-size>40</pool-max-size>
    <pool-max-wait>30000</pool-max-wait>
    <pool-max-idle>20</pool-max-idle>
    <pool-remove-abandoned>true</pool-remove-abandoned>
    <pool-remove-abandoned-timeout>300</pool-remove-abandoned-timeout>
    <pool-test-on-borrow>false</pool-test-on-borrow>
    <pool-test-while-idle>true</pool-test-while-idle>
    <validation-query>select 1</validation-query>
    <min-evictable-idle-time-millis>60000</min-evictable-idle-time-millis>
    <time-between-eviction-runs-millis>300000</time-between-eviction-runs-millis>
  </jdbc-datasource>
</App-database-config>

Step 6-2: アプリケーション設定の最適化

# App JVM設定の調整
sudo vim /opt/App/bin/setenv.sh

# メモリ設定例(4GB RAMの場合)
JVM_MINIMUM_MEMORY="1024m"
JVM_MAXIMUM_MEMORY="2048m"
JVM_RESERVED_CODE_CACHE_SIZE="512m"

# GC設定の最適化
CATALINA_OPTS="-XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+UseStringDeduplication"

# ログ設定の確認
sudo vim /opt/App/atlassian-App/WEB-INF/classes/log4j.properties

Step 6-3: アプリケーション再起動と動作確認

# Appサービス停止
sudo systemctl stop App

# 設定ファイルの構文確認
sudo -u App /opt/App/bin/catalina.sh configtest

# データベース接続テスト
sudo -u App psql -h App-aurora-cluster.cluster-xxxxxxxxx.ap-northeast-1.rds.amazonaws.com \
                  -U Appadmin \
                  -d Appdb \
                  -c "SELECT version();"

# Appサービス開始
sudo systemctl start App

# サービス状態確認
sudo systemctl status App

# アプリケーションログ監視
sudo tail -f /opt/App/logs/catalina.out
sudo tail -f /opt/App/logs/atlassian-App.log

✅ 移行後の確認とテスト

機能テスト項目

基本機能確認

  • ログイン機能: 既存ユーザーでのログイン確認
  • プロジェクト表示: 全プロジェクトの表示確認
  • 課題検索: フィルタ機能の動作確認
  • 課題作成: 新規課題作成とワークフロー確認
  • 添付ファイル: ファイルアップロード/ダウンロード確認

パフォーマンステスト

  • レスポンス時間: 主要画面の応答時間測定
  • データベース性能: 大量データ検索の実行時間確認
  • 同時接続: 複数ユーザーでの同時アクセステスト

データ整合性確認

-- データベース接続確認
\l

-- テーブル数確認
SELECT count(*) FROM information_schema.tables WHERE table_schema = 'public';

-- 主要テーブルのレコード数確認
SELECT 'Appissue' as table_name, count(*) as record_count FROM Appissue
UNION ALL
SELECT 'project' as table_name, count(*) as record_count FROM project
UNION ALL
SELECT 'cwd_user' as table_name, count(*) as record_count FROM cwd_user;

-- インデックス確認
SELECT schemaname, tablename, indexname, indexdef 
FROM pg_indexes 
WHERE schemaname = 'public' 
ORDER BY tablename, indexname;

🚨 トラブルシューティング

よくある問題と対処法

MGNレプリケーション関連

問題: レプリケーションが開始されない
原因: ネットワーク接続またはIAM権限の問題
対処法:

  • セキュリティグループでTCP 1500ポートが開放されているか確認
  • IAMユーザーにMGN関連権限が付与されているか確認
  • オンプレミス側でaws-replication-agentサービスの状態確認

問題: レプリケーション速度が遅い
原因: 帯域制限またはディスクI/O性能の問題
対処法:

  • レプリケーション設定でbandwidth-throttlingを調整
  • レプリケーションサーバーのインスタンスタイプを上位に変更

DMS移行関連

問題: DMS接続テストが失敗する
原因: データベース接続設定またはネットワーク設定の問題
対処法:

  • PostgreSQLのpg_hba.confで接続許可設定を確認
  • セキュリティグループでPort 5432が開放されているか確認
  • エンドポイント設定のユーザー名・パスワードを再確認

問題: データ移行中にエラーが発生
原因: データ型の不整合またはConstraint違反
対処法:

  • ソースとターゲットのスキーマ定義を比較確認
  • テーブルマッピングルールを見直し
  • ログを詳細に確認してエラーの根本原因を特定

アプリケーション起動関連

問題: App起動時にデータベース接続エラー
原因: dbconfig.xmlの設定またはネットワーク接続の問題
対処法:

  • Aurora接続文字列の正確性を確認
  • セキュリティグループでAppからAuroraへの通信が許可されているか確認
  • psqlコマンドで手動接続テストを実行

問題: App起動が異常に遅い
原因: データベース接続プールの設定またはAuroraの性能問題
対処法:

  • 接続プールサイズを環境に応じて調整
  • Auroraインスタンスクラスを上位に変更
  • データベースインデックスの確認と最適化

問題: 添付ファイルにアクセスできない
原因: EFSマウントまたはファイル権限の問題
対処法:

  • EFSマウント状態を確認: df -h | grep efs
  • ファイル権限を確認: ls -la /opt/App/shared/
  • AppプロセスがEFSに書き込み権限を持つか確認

性能最適化のポイント

データベース最適化

Aurora接続設定の調整:

<!-- 高負荷環境用の推奨設定 -->
<pool-min-size>10</pool-min-size>
<pool-max-size>50</pool-max-size>
<pool-max-wait>30000</pool-max-wait>
<pool-max-idle>25</pool-max-idle>
<pool-test-on-borrow>true</pool-test-on-borrow>
<pool-test-while-idle>true</pool-test-while-idle>
<validation-query>SELECT 1</validation-query>
<validation-query-timeout>3</validation-query-timeout>

Auroraパラメータグループ設定:

  • shared_preload_libraries = 'pg_stat_statements'
  • max_connections = 200
  • shared_buffers = 256MB
  • effective_cache_size = 1GB
  • work_mem = 4MB

EFS最適化

スループットモード設定:

# プロビジョンドスループットモードに変更
aws efs modify-file-system \
    --file-system-id fs-xxxxxxxxx \
    --throughput-mode provisioned \
    --provisioned-throughput-in-mibps 500

キャッシュ設定の追加:

# EFS Utilsの最適化設定
echo "fs-xxxxxxxxx.efs.ap-northeast-1.amazonaws.com:/ /opt/App/shared efs tls,_netdev,regional,iam" >> /etc/fstab

📊 監視・運用

CloudWatch監視設定

カスタムメトリクス設定

Appアプリケーション監視:

# CloudWatch Agentインストール
wget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm
sudo rpm -U ./amazon-cloudwatch-agent.rpm

# 設定ファイル作成
sudo tee /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json << 'EOF'
{
    "agent": {
        "metrics_collection_interval": 60,
        "run_as_user": "root"
    },
    "logs": {
        "logs_collected": {
            "files": {
                "collect_list": [
                    {
                        "file_path": "/opt/App/logs/atlassian-App.log",
                        "log_group_name": "/aws/ec2/App/application",
                        "log_stream_name": "{instance_id}"
                    },
                    {
                        "file_path": "/opt/App/logs/catalina.out",
                        "log_group_name": "/aws/ec2/App/catalina",
                        "log_stream_name": "{instance_id}"
                    }
                ]
            }
        }
    },
    "metrics": {
        "namespace": "App/Application",
        "metrics_collected": {
            "cpu": {
                "measurement": ["cpu_usage_idle", "cpu_usage_iowait", "cpu_usage_user", "cpu_usage_system"],
                "metrics_collection_interval": 60
            },
            "disk": {
                "measurement": ["used_percent"],
                "metrics_collection_interval": 60,
                "resources": ["*"]
            },
            "mem": {
                "measurement": ["mem_used_percent"],
                "metrics_collection_interval": 60
            }
        }
    }
}
EOF

# CloudWatch Agent開始
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
    -a fetch-config \
    -m ec2 \
    -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json \
    -s

アラート設定

重要なアラート項目:

メトリクス 閾値 アクション
CPU使用率 80%以上が5分間継続 運用チームに通知
メモリ使用率 85%以上が3分間継続 即座にエスカレーション
ディスク使用率 90%以上 容量拡張の検討
Aurora接続数 最大接続数の80%以上 接続プール設定の見直し
EFSスループット プロビジョンド値の90%以上 スループット増加の検討

バックアップ戦略

自動バックアップ設定

Auroraバックアップ:

# 自動バックアップの有効化(既に設定済み)
aws rds modify-db-cluster \
    --db-cluster-identifier App-aurora-cluster \
    --backup-retention-period 30 \
    --preferred-backup-window "03:00-04:00"

# 手動スナップショット作成
aws rds create-db-cluster-snapshot \
    --db-cluster-identifier App-aurora-cluster \
    --db-cluster-snapshot-identifier App-manual-snapshot-$(date +%Y%m%d%H%M%S)

EFSバックアップ:

# AWS Backupサービスを使用したEFSバックアップ
aws backup create-backup-plan \
    --backup-plan '{
        "BackupPlanName": "AppEFSBackupPlan",
        "Rules": [
            {
                "RuleName": "DailyBackup",
                "TargetBackupVault": "default",
                "ScheduleExpression": "cron(0 3 ? * * *)",
                "Lifecycle": {
                    "DeleteAfterDays": 30
                },
                "RecoveryPointTags": {
                    "Environment": "Production",
                    "Application": "App"
                }
            }
        ]
    }'

災害復旧計画

RTO/RPO目標

項目 目標値 実現方法
RTO (復旧時間目標) 4時間以内 Multi-AZ配置とオートスケーリング
RPO (復旧ポイント目標) 1時間以内 継続的バックアップとPoint-in-Time回復

災害復旧手順

Aurora障害時の復旧:

  1. 自動フェイルオーバーの確認(Multi-AZ環境)
  2. Point-in-Time回復の実行(必要に応じて)
  3. 接続文字列の更新(クラスター書き込みエンドポイント)
  4. アプリケーションの再起動

EFS障害時の復旧:

  1. AWS Backupからの復元
  2. 新しいEFSファイルシステムの作成
  3. マウント設定の更新
  4. アプリケーション設定の変更

🔒 セキュリティ対策

セキュリティベストプラクティス

ネットワークセキュリティ

セキュリティグループ設定の原則:

  • 最小権限の原則に基づくアクセス制御
  • 送信元IPアドレスの明確な制限
  • 不要なポートの完全な閉鎖
  • 定期的な設定レビューの実施

VPCエンドポイント活用:

# S3 VPCエンドポイント作成(ログやバックアップ用)
aws ec2 create-vpc-endpoint \
    --vpc-id vpc-xxxxxxxxx \
    --service-name com.amazonaws.ap-northeast-1.s3 \
    --route-table-ids rtb-xxxxxxxxx

# DMS VPCエンドポイント作成
aws ec2 create-vpc-endpoint \
    --vpc-id vpc-xxxxxxxxx \
    --service-name com.amazonaws.ap-northeast-1.dms \
    --subnet-ids subnet-xxxxxxxxx \
    --security-group-ids sg-xxxxxxxxx

データ暗号化

保存時暗号化:

  • Aurora: KMS暗号化の有効化
  • EFS: デフォルト暗号化の設定
  • EBS: KMS暗号化の適用
  • S3: SSE-S3またはSSE-KMSの使用

転送時暗号化:

  • HTTPS/TLS通信の強制
  • データベース接続のSSL化
  • VPN接続による管理アクセス

アクセス制御

IAMベストプラクティス:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "rds:DescribeDBClusters",
                "rds:DescribeDBInstances"
            ],
            "Resource": "arn:aws:rds:ap-northeast-1:123456789012:cluster:App-aurora-cluster"
        },
        {
            "Effect": "Allow",
            "Action": [
                "efs:DescribeFileSystems",
                "efs:DescribeMountTargets"
            ],
            "Resource": "arn:aws:elasticfilesystem:ap-northeast-1:123456789012:file-system/fs-xxxxxxxxx"
        }
    ]
}

コンプライアンス対応

監査ログ設定

CloudTrail設定:

# CloudTrail作成(全APIコール記録)
aws cloudtrail create-trail \
    --name App-audit-trail \
    --s3-bucket-name App-audit-logs-bucket \
    --include-global-service-events \
    --is-multi-region-trail \
    --enable-log-file-validation

# CloudTrail開始
aws cloudtrail start-logging \
    --name App-audit-trail

VPCフローログ設定:

# VPCフローログ有効化
aws ec2 create-flow-logs \
    --resource-type VPC \
    --resource-ids vpc-xxxxxxxxx \
    --traffic-type ALL \
    --log-destination-type cloud-watch-logs \
    --log-group-name VPCFlowLogs \
    --deliver-logs-permission-arn arn:aws:iam::123456789012:role/flowlogsRole

📈 最適化・改善提案

パフォーマンスチューニング

Appアプリケーション最適化

JVM設定の調整:

# 大規模環境用のJVM設定例(8GB RAM)
export JVM_MINIMUM_MEMORY="2048m"
export JVM_MAXIMUM_MEMORY="4096m"
export JVM_RESERVED_CODE_CACHE_SIZE="1024m"

# G1GCの詳細設定
export CATALINA_OPTS="
    -XX:+UseG1GC
    -XX:MaxGCPauseMillis=200
    -XX:+UseStringDeduplication
    -XX:G1HeapRegionSize=16m
    -XX:+UnlockExperimentalVMOptions
    -XX:G1NewSizePercent=20
    -XX:G1MaxNewSizePercent=40
    -XX:G1MixedGCLiveThresholdPercent=35
    -XX:+AlwaysPreTouch
    -XX:+UseLargePages
    -XX:+DisableExplicitGC
"

データベース最適化

定期メンテナンススクリプト:

-- 統計情報の更新
ANALYZE;

-- 不要データのクリーンアップ
DELETE FROM Appissue WHERE resolution IS NOT NULL AND updated < (CURRENT_DATE - INTERVAL '2 years');

-- インデックスの再構築
REINDEX DATABASE Appdb;

-- バキューム実行
VACUUM ANALYZE;

コスト最適化

リソース最適化提案

Auto Scalingの実装:

# Auto Scalingグループ作成
aws autoscaling create-auto-scaling-group \
    --auto-scaling-group-name App-asg \
    --launch-template LaunchTemplateName=App-template,Version='$Latest' \
    --min-size 1 \
    --max-size 3 \
    --desired-capacity 2 \
    --target-group-arns arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/App-tg \
    --health-check-type ELB \
    --health-check-grace-period 300 \
    --vpc-zone-identifier "subnet-xxxxxxxxx,subnet-yyyyyyyyy"

# スケーリングポリシー作成
aws autoscaling put-scaling-policy \
    --auto-scaling-group-name App-asg \
    --policy-name App-scale-out \
    --policy-type TargetTrackingScaling \
    --target-tracking-configuration '{
        "TargetValue": 70.0,
        "PredefinedMetricSpecification": {
            "PredefinedMetricType": "ASGAverageCPUUtilization"
        }
    }'

リザーブドインスタンス活用:

  • EC2インスタンス: 1年または3年のリザーブドインスタンス購入
  • Aurora: リザーブドDBインスタンス購入
  • 使用量に基づく適切なインスタンスタイプ選択

継続的改善

DevOps統合

CI/CD パイプライン構築:

# .github/workflows/App-deployment.yml
name: App Deployment Pipeline

on:
  push:
    branches: [main]
    paths: ['App-config/**']

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-1

      - name: Deploy configuration changes
        run: |
          aws ssm send-command \
            --instance-ids i-xxxxxxxxx \
            --document-name "AWS-RunShellScript" \
            --parameters 'commands=["sudo systemctl restart App"]'

📚 まとめ

移行プロジェクトの成果

技術的成果

項目 移行前(オンプレミス) 移行後(AWS) 改善効果
可用性 99.0% 99.9% SLA向上
復旧時間 8時間 1時間 復旧時間87.5%短縮
バックアップ 手動、週次 自動、日次 運用工数削減
セキュリティ 基本的な対策 多層防御 セキュリティレベル向上
スケーラビリティ 固定リソース 自動スケーリング 負荷対応能力向上

運用面での改善

自動化による効果:

  • デプロイ時間: 4時間 → 30分(87.5%短縮)
  • 障害復旧: 手動対応 → 自動復旧
  • 監視・アラート: 限定的 → 包括的監視

コスト効率化:

  • 初期投資: ハードウェア購入不要
  • 運用コスト: 従量課金による最適化
  • 人的リソース: インフラ保守からビジネス価値創出へシフト

今後の発展計画

短期計画(3ヶ月以内)

  1. パフォーマンス最適化

    • Auroraパラメータチューニング
    • EFSスループット最適化
    • JVMパラメータ調整
  2. 監視強化

    • カスタムメトリクス追加
    • アラート閾値の精緻化
    • ダッシュボードの充実
  3. セキュリティ強化

    • WAF導入
    • セキュリティ監査の実施
    • アクセス権限の最小化

中期計画(6ヶ月以内)

  1. ディザスタリカバリ

    • マルチリージョン構成の検討
    • 自動フェイルオーバー機能の実装
    • 復旧手順の自動化
  2. コンテナ化検討

    • ECS/Fargateへの移行検討
    • Kubernetesクラスター構築
    • マイクロサービス化の計画
  3. AI/ML活用

    • ログ分析の自動化
    • 異常検知システムの導入
    • 予測分析による容量計画

ベストプラクティス

移行プロジェクト成功の要因

  1. 段階的アプローチ

    • リスクを最小化する段階的移行
    • 各フェーズでの検証とロールバック計画
    • 十分なテスト期間の確保
  2. 自動化の重視

    • 手動作業の最小化
    • Infrastructure as Codeの採用
    • CI/CDパイプラインの構築
  3. チーム体制

    • クロスファンクショナルチームの編成
    • 明確な役割分担と責任の所在
    • 定期的なコミュニケーション
  4. リスク管理

    • 包括的なリスク分析
    • 複数のコンティンジェンシープラン
    • ステークホルダーとの継続的な調整

次回移行に向けた教訓

技術面での学び:

  • MGNの事前テストの重要性
  • DMSパフォーマンスチューニングの必要性
  • EFS性能要件の事前評価の重要性

プロジェクト管理面での学び:

  • 移行スケジュールのバッファ確保
  • ステークホルダーとの密な連携
  • ドキュメント整備の重要性

本移行を通じて、システムのクラウド化を成功させることができました。AWS マネージドサービスの活用により、可用性・拡張性・セキュリティの全面的な向上を実現し、今後のビジネス成長を支える基盤を構築することができました。

継続的な改善とモニタリングを通じて、さらなる最適化を図り、組織全体のDX推進に貢献していきます。

Last modified: 2025-07-15

Author