メニュー

デジタル庁GCASガイド

Replatform システム移行ノウハウ(クラウドサービス活用)(AWS編)

2023/03/27 公開

Replatform システム移行ノウハウ(クラウドサービス活用)

システムをガバメントクラウドに移行する際に必要となるプロセスにおいて、クラウドを活用した構成へ移行する際の考慮事項を整理した文書である。

はじめに

システムをクラウドに移行する際に、本書で記載する考慮事項についての検討を行い、クラウドのメリットを最大限活用することを推奨する。
アプリケーションへの影響が大きい場合は、以下のノウハウを参考に可能な限り実現すること。

クラウド移行においては、仮想マシンなどのリソースが柔軟に確保できるクラウドの特徴を活かし、オートスケールの導入を推奨とする。オートスケールよって、システムの負荷に応じてサーバの台数を適切に増減させることで、コストの最適化やシステムの負荷への柔軟な対応が可能となる。

さらに、アプリケーションのコンテナ化を実施すると、アプリケーション自身とライブラリ等の依存関係を全て含んだ形でイメージ化できるため、クラウド上でのデプロイを効率的に実行することができる。コンテナ化されたアプリケーションは、OS レベルの仮想化は不要であり高速に起動するため、オールスケールによるサーバ台数の増加とも相性が良い。また、複数環境へのデプロイにおいては、同一のコンテナイメージをまずテスト環境で検証し、その次に本番環境に適用することが可能であり、CI/CD として継続的なシステムのアップデートを取り入れることが容易となる。
そして、コンテナのデプロイ先としてフルマネージドなサービスを選択した場合は、コンテナをホストする仮想サーバの管理すら不要となり、運用コストの削減が期待できる。

また、複数のデータセンターを利用可能なクラウドの特徴を活かし、複数のアベイラビリティゾーン(AZ)を利用する構成を推奨とする。複数の AZ を利用することで、可用性向上のメリットが得られる。

オートスケール対応

本章でのコンピューティングサービスは、仮装マシンのサービスとしては Amazon EC2 を前提とする。

また、コンテナ実行環境のサービスとしては、コントロールプレーンとして Amazon ECS を、データプレーンとして AWS Fargate を前提とする。Amazon ECS はフルマネージドなコントロールプレーンであり、他の AWS サービスと高度に連携しコンテナを大規模に実行することが可能である。AWS Fargate は、コンテナホストとしての EC2 インスタンスのプロビジョン、スケール、管理などが不要になり、仮想マシンを意識しないシームレスなスケーリングを実現するものである。

オートスケールに関して、仮想マシン(Amazon EC2) と コンテナ(Amazon ECS on AWS Fargate) の両方に共通する考慮事項やそれぞれのサービスに固有の考慮事項について述べる。

仮想マシンとコンテナ共通

セッション管理

セッション情報はサーバの外部に保持する必要がある。オートスケールによってサーバの台数が増減する場合であっても、稼働を継続する各サーバでセッション情報を利用する処理を実行するためである。
また、セッション情報をサーバの外部に保持することで、クライアントからのリクエストにどのサーバでも応答できるようになり、ロードバランサーがリクエストの振り分け先をクライアントごとに固定化するスティッキーなセッションも不要となる。

セッション情報の保存先としては、マネージドなデータベースサービスを利用するものとする。検討すべきサービスは以下の通りである。

サービス名種別特徴
Amazon ElastiCacheインメモリRedis、Memcached 互換。マイクロ秒単位の応答時間
Amazon DynamoDBキーバリュー規模に関係なく、数ミリ秒のレスポンス。毎秒 2,000 万件を超えるリクエストをサポート
Amazon RDSリレーショナルAmazon Aurora や MySQL などのデータベースエンジンを選択可能
Amazon MemoryDBインメモリRedis 互換。データの耐久性、一貫性、および回復性を提供

なお、セッション情報としてどのようなデータを保管すべきかも考慮すべき事項である。サーバ側での処理はステートレスなものとするべきであり、複数の処理にまたがるトランザクションの状態をセッション情報として保管することは避けるべきである。セッション情報は、ユーザの認証状態を示す情報のような最低限の情報のみに限定することが望ましい。

性能検証

オートスケールを導入した場合に、システムが対応可能な同時アクセス数などの性能特性を性能検証によって把握することを推奨する。システムが想定する最大の同時リクエスト数や、アクセスのパターンを踏まえて負荷試験のシナリオを作成し、性能検証を行うことを推奨する。性能検証の対象とするアプリケーションに応じて、性能検証で確認すべき項目を決定する必要がある。Web API を提供するアプリケーションを例とした場合の性能検証による一般的な確認項目と達成基準は以下の通りである。

確認項目達成基準
レイテンシ非機能要件で定められた最大レイテンシを超えていないこと
スループット非機能要件で定められた単位時間あたりのリクエスト数以上の処理が可能であること
ステータスコード高負荷時及び負荷の継続時においても処理が成功していること(HTTP のレスポンスステータスコードによる確認)

また、利用者の増加などによる定常的なアクセスの増加を考慮して、性能面で問題が発生しないように、オートスケールの設定は継続的に見直していく必要があることにも留意すべきである。オートスケールの設定の中で、スケーリングの基準となる CloudWatch メトリクスは、事前定義されたものとカスタムメトリクスが利用可能である。スケーリングの基準となる CloudWatch メトリクスとして代表的なものは下記の通りである。

項目仮想マシン(Amazon EC2)コンテナ(Amazon ECS)
CPU 使用率ASGAverageCPUUtilization として事前定義ECSServiceAverageCPUUtilization として事前定義
メモリ使用率カスタムメトリクスとして作成が必要ECSServiceAverageMemoryUtilization として事前定義
ALB リクエスト数ALBRequestCountPerTarget として事前定義左記に同じ

スケーリングの基準となる CloudWatch メトリクスに対して設定した値や、最小キャパシティー及び最大キャパシティーの値を継続的に見直していく必要がある。また、動的スケーリングのスケーリングポリシーのタイプ(ターゲット追跡スケーリングまたはステップスケーリング)も必要に応じて見直すものとする。スケーリングポリシーについてはAmazon EC2 Auto Scaling の動的スケーリングOpens in new tabまたはサービスのオートスケーリングOpens in new tabを参照のこと。

また、システムへの一時的なアクセスの増加が見込まれる場合には、あらかじめオートスケールの最小キャパシティーの増加を設定しておくスケジュールスケーリングを導入することも有効である。スケジュールスケーリングでは指定の日時に 1 度だけスケールアウトする設定や、cron 式を用いて定期的にスケールアウトする設定などが実現可能である。スケジュールスケーリングについてはAmazon EC2 Auto Scaling のスケジュールされたスケーリングOpens in new tabまたはApplication Auto Scaling のスケジュールされたスケーリングOpens in new tabを参照のこと。

なお、Amazon EC2 インスタンスからシステムに対する性能検証を実施し、Amazon EC2 インスタンスが負荷の発生元になる場合、Amazon EC2 Testing PolicyOpens in new tabにおいて「ネットワーク負荷テスト」に該当するかどうかの条件が記載されている。「ネットワーク負荷テスト」に該当する場合は、AWS への事前の申請が必要となるため、リンクの内容を確認し、「ネットワーク負荷テスト」に該当するかどうかを判断すること。「ネットワーク負荷テスト」に該当するか不明確な場合は、Amazon EC2 Testing PolicyOpens in new tabに記載の方法で、AWS への問い合わせが可能である。

仮想マシンの場合

ファイル

処理の中間結果を保存する一時ファイルやクライアントからアップロードされたファイル等はサーバの外部に保存する必要がある。オートスケールによってサーバの台数が増減する場合でもあっても、稼働を継続する各サーバでファイルを利用する処理を実行するためである。

ファイルの保存先としては、マネージドなストレージサービスを利用するものとする。検討すべきサービスは Simple Storage Service(S3)である。

サービス名種別特徴
Simple Storage Service(S3)オブジェクトストレージHTTP プロトコルの Web API を経由してオブジェクトの操作を行う。容量無制限で高い耐久性を備える

なお、ミドルウェアの制約等によるやむを得ない理由がある場合を除き、ファイルストレージの利用は避けるものとする。ファイルストレージが必要となる場合であっても、マネージドなサービスである Elastic File System(EFS) や FSx for Windows の利用を検討するものとする。

ログ管理

サーバが出力する OS/ミドルウェア/アプリケーションのログのうち、永続化が必要なログは、マネージドサービスである CloudWatch Logs にアップロードする。これにより、スケールインによってサーバがシャットダウンされる場合であっても、ログを継続的に保管することができる。

CloudWatch はモニタリングに関する様々な機能を提供しており、CloudWatch Logs はその機能の一つである。また、CloudWatch Logs に保管したログは、CloudWatch Insights を利用して検索や可視化することも可能である。

CloudWatchの概要
図 2. CloudWatch の概要

ログファイルおよび Windows イベントログを CloudWatch エージェントで収集することができる。サーバへの CloudWatch エージェントの導入方法についてはCloudWatch エージェントのインストールOpens in new tab を参照のこと。

また、CloudWatch エージェント設定ファイルによって、収集対象のログファイルや、保管先の CloudWatch Logs のロググループ等を変更することができる。詳細については、CloudWatch エージェント設定ファイル: Logs セクションOpens in new tabを参照のこと。

なお、CloudWatch Logs のロググループは、ログの保持期間を設定することで自動的にログを削除することが可能である。CloudWatch Logs の料金は、取り込んだログの容量や保持するログの容量によって決まる。そのため、CloudWatch Logs にアップロードすべきログの種類の精査や、ログの保持期間の設定により、CloudWatch Logs の料金を適正に保つことが推奨される。

また、アプリケーションのモニタリングで使用しないログの場合は、ClodWatch Logs ではなく S3 をアップロード先として選択することも可能である。S3 では、CloudWatch Logs で提供されているログの検索機能はないが、長期保管の際にはコストメリットを得られることが多い。ただし、Amazon EC2 から S3 にログを定期的にアップロードするためには、AWS CLI によるログのアップロードを定期実行するスクリプトの作り込み等が必要である。

パラメータ管理

サーバの設定に関するパラメータは、サーバの外部に保存するものとする。パラメータをサーバの外部に保管し、環境依存の要素を排除することで以下のメリットが得られる。

  • 開発環境や本番環境などの複数面の環境ごとにアプリケーションをビルドする必要がなくなり、デプロイが容易
  • 設定を変更する際にアプリケーションの再ビルドは不要となり、設定変更に対して柔軟に対応可能

サーバの設定に関するパラメータとして、以下の例が挙げられる。

  • 認証情報(DB 接続ユーザ/パスワードなど)
  • 接続先エンドポイント情報
  • 接続先データベース/ストレージ情報(S3 バケット名/DynamoDB テーブル名など)
  • タイムアウト値、ログレベル、フィーチャーフラグなど

パラメータの保管先としては、マネージドなパラメータ保管サービスとする。検討すべきサービスは下記の通り。

サービス名種別特徴
Parameter Storeパラメータ保管AWS Systems Manager の 1 機能として提供。設定値を階層型で保存。AMI ID など AWS が提供する値あり
AWS Secrets Managerシークレット保管ライフサイクル管理を備えたシークレット専用のストア。自動的にシークレットのローテーションが可能

EC2 の場合では、Parameter Store 及び AWS Secrets Manager から設定を取得するためには、AWS SDK や AWS CLI などを利用する必要がある。また、起動時に Linux インスタンスでコマンドを実行するOpens in new tabを参考にし、EC2 起動時の処理の一環として、設定を自動的に取得することも可能である。

コンテナの場合

ファイル

仮想マシン の ファイルと同様に、ファイルはコンテナの外部に保存するものとし、保存先としては Simple Storage Service(S3)を第一優先とする。
コンテナの場合であっても、オートスケールによってコンテナの台数が増減するため、ファイルをコンテナの外部に保存しておく必要がある。

AWS Fargate でホストされている各 Amazon ECS タスクは、プロビジョニングされる際に、バインドマウントのためにエフェメラルストレージが利用可能となる。しかしながら、エフェメラルストレージは、コンテナのライフサイクルと紐づけられており、タスクが停止するなど、バインドマウントを使用するすべてのコンテナが停止すると、データが削除されてしまう。エフェメラルストレージの使用はやむを得ない場合のみに限定し、ファイルの保存先としては Simple Storage Service(S3)を第一優先とすべきである。

ログ管理

コンテナ内のアプリケーションは、ログを標準出力に出力するものとする。標準出力に出力されたログは、ログドライバーによって、CloudWatch Logs 等に保管される。これにより、スケールインによってコンテナがシャットダウンされる場合であっても、ログを継続的に保管することができる。

また、ログを標準出力に出力することで、ログの出力先の変更が柔軟に行える効果も期待できる。コンテナ内のアプリケーションは標準出力にログを出力するのみでよく、ログの保管先の変更はログドライバーの設定変更だけで実現できるため、アプリケーションの改修は不要である。

Amazon ECS で利用可能なログドライバーは下記の通り。

ログドライバー
図 3. Amazon ECS で利用可能なログドライバー

ログドライバー名ログ転送可能サービス特徴
awslogsCloudWatch Logsシンプルな設定内容で実現でき、ログ転送のための追加のリソースは不要
FirelensCloudWatch Logs
S3
Amazon OpenSearch Service
Kinesis Data Firehose
Kinesis Data Streams
アプリケーション用とは異なるサイドカーコンテナとして、ログ転送用のコンテナを用意。コンテナイメージ内に Firelens の設定ファイルを含めることで、ボリュームに出力したファイル経由でのログ転送も可能

また、awslogs と Firelens のどちらを利用するかの選択に関して、参考となる情報は下記の通り。

ログドライバー名メリットデメリット
awslogs設定が簡単
ログ収集のためのリソース不要
ログの種類毎に異なる場所に格納するなど高度な処理は難しい
CloudWatch Logs にしか転送できない
CloudWatch Logs の料金に注意が必要
Firelens(カスタム設定ファイルなし)設定が簡単
S3 など CloudWatch 以外の場所に転送可能
AWS が提供する fluent-bit のイメージが利用可能
複数の転送先は指定不可
ログの種類毎の異なる場所に格納するなど高度な処理は難しい
サイドカーのリソースが必要
Firelens(カスタム設定ファイルあり)標準出力以外にファイルログの収集も可能
S3 など CloudWatch 以外の場所に転送可能
複数の転送先が設定可能
ログの種類毎に複数の場所に格納するなど任意の処理が可能
自動生成される設定はカスタマイズが困難
fluentd/fluent-bit の設定が必要
サイドカーのリソースが必要
AWS が提供する fluent-bit に設定ファイルの追加が必要

パラメータ管理

EC2 の パラメータ管理と同様に、パラメータはコンテナの外部に保存するものとする。
パラメータの保管先としては、EC2 の パラメータ管理と同様にマネージドなパラメータ保管サービスとする。

なお、Parameter Store や AWS Secrets Manager に保管されたパラメータは、コンテナの環境変数として利用することができる。コンテナの定義においてパラメータへの参照を記載することで、コンテナ内のアプリケーションは環境変数としてパラメータを取得することができる。コンテナの定義における記載の方法は以下を参照のこと。

シャットダウン処理

オートスケールなどによってコンテナが終了する場合に、終了シグナルをハンドリングし、コンテナを安全に終了できるようにすべきである。

コンテナの終了シグナル
図 4. コンテナの終了シグナル

コンテナ終了時には、まず SIGTERM のシグナルが送信され、設定されたタイムアウト時間の経過後に SIGKILL のシグナルが送信され、コンテナが終了される。
SIGTERM のハンドリングとして、アプリケーションのグレースフルな終了処理や、ファイルの退避などが挙げられる。また、SIGKILL が発生されるタイムアウト時間に関しても、Web API を提供する コンテナ の場合は、Web API のレスポンスの返却までにかかる時間を考慮して設定する必要がある。タイムアウト時間が短すぎると、クライアントが Web API のレスポンスを受け取る前にコンテナが終了され、クライアントにエラーが返却されてしまう。なお、タイムアウト時間の設定である、ECS タスク定義の stopTimeout の最大値は 120 秒であることに留意すべきである。stopTimeout の設定値の詳細はコンテナのタイムアウトOpens in new tabを参照のこと。

その他シャットダウン処理に関する詳細はECS のアプリケーションを正常にシャットダウンする方法Opens in new tabを参照のこと

マルチ AZ 対応

冗長性と高可用性を実現するために、複数のアベイラビリティゾーン(AZ)を活用するものとする。VPC が複数の AZ(マルチ AZ)で構成されていることを前提に、マルチ AZ にサーバを配置することで、仮に 1 つの AZ で障害が発生した場合でもシステムの稼働を続けられるようになり、可用性を高めることができる。

負荷分散

マルチ AZ に配置された複数のサーバを組み合わせてシステムを構成するために、リクエストを各サーバに分散する負荷分散の仕組みが必要である。

ロードバランサー導入

負荷分散には、マネージドな負荷分散サービスである Elastic Load Balancing(ELB) を利用するものとする。ELB はマルチ AZ への負荷分散に対応しており、ELB 自体の性能増減は自動的に行われる。ELB はリクエストを振り分けるサーバが正常に稼働しているかをチェックし、異常が発生している場合には、正常に稼働しているサーバのみで負荷分散を行う。

また、クライアントは、ELB のホスト名を使ってでサーバにアクセスするものとする。これにより、ELB がリクエストを振り分けるサーバの増減を意識せずにクライアントはサーバに接続することができる。

ELB で提供されるロードバランサーは以下の通り。

ロードバランサー対応プロトコル特徴
Application Load Balancer(ALB)HTTP/HTTPSL7 ロードバランサー。コンテンツベースのルーティングやユーザ認証機能に対応
Network Load Balancer(NLB)TCP/TLS/UDPL4 ロードバランサー。高可用性、高スループット、低レイテンシを備える
Classic Load Balancer(CLB)HTTP/HTTPS/TCP以前の世代のロードバランサーであり、ほとんどのケースにおいては、ALB または NLB でカバー可能。CLB が必要となる特殊なケースは BenefitsOpens in new tab を参照のこと

AZ 間通信

AZ 間は、高帯域幅・低レイテンシーのネットワークで相互接続されているものの、AZ をまたぐ通信の回数が増えると、わずかな遅延が蓄積し、処理の全体的なレイテンシに影響が出る可能性がある。AZ をまたぐ通信において、レイテンシの低下が懸念される場合には、通信の回数を減らすように考慮する必要がある。

SQL 呼び出し効率化

サーバをマルチ AZ の冗長構成にした場合、サーバが存在する AZ とは異なる AZ に配置されたデータベースへ接続することがあり得る。
その際に、処理対象のデータ件数が多い場合には、1 件ごとにデータベースを更新することは避け、一括でデータベースを更新するようにクエリを見直す必要がある。

これにより、データベースに対する AZ を跨いだ通信の回数を削減することができ、処理の全体的なレイテンシを改善する効果が期待できる。

クエリ効率化
図 5. クエリ効率化の例

その他

アプリケーションの移行に関して、その他の考慮事項として、アプリケーションの構成方法や他サービスとの連携の観点での考慮事項を挙げる。

依存関係

サーバ上で稼働するアプリケーションは、必要なライブラリやパッケージが暗黙的に存在することに依存せず、明示的に依存関係を宣言するものとする。これにより、アプリケーションが配備される環境への暗黙的な依存を避け、安定的にアプリケーションを稼働させることができる。

各プログラミング言語での代表的な依存関係の管理ツールと宣言マニフェストは以下の通り。これらのツールを利用して、依存関係を網羅し宣言を行う。

プログラミング言語管理ツール宣言マニフェスト
Javamavenpom.xml
Javagradlebuild.gradle
Node.jsnpmpackage.json
Rubybundlergemfile
Pythonpiprequirements.txt
C#NuGet.nuspec
GoGo Modulego.mod

また、コンテナイメージを作成する場合には、Dockerfile において、必要なライブラリのインストールを網羅し、依存関係を宣言する必要がある。

サービス呼び出し

サーバがアクセスするデータベースやストレージは、ネットワーク越しにアクセスするバックエンドサービスとして扱うべきである。バックエンドサービスには外部の API サービスも含まれると考え、バックエンドサービスの遅延や停止の可能性を考慮する必要がある。具体的には、以下のような処理を考慮する必要がある。

  • リトライ
    • 一時的な中断を考慮し、バックエンドへのリクエストはリトライする
  • タイムアウト
    • 長期の待ち受け処理を避けるため、タイムアウトを設ける

なお、リトライすべき条件やリトライ回数、タイムアウトの秒数などは、バックエンドサービスを呼び出すアプリケーションや呼び出し先のバックエンドサービスの仕様や特性を考慮して設定を行う必要がある。

また、各プログラミング言語に対応した AWS SDK では、AWS サービスの呼び出しに対してリトライやタイムアウトが実装されている。リトライの回数やタイムアウトの時間等の設定の変更については、各 AWS SDK のドキュメントを参照のこと(AWS SDK for Jave の例: クライアント設定Opens in new tab)。

AWS SDK では、エクスポネンシャルバックオフと呼ばれる、リトライ間の待機時間を徐々に長くするリトライの方式が実装されている。アプリケーションでリトライ処理を独自に実装する必要がある場合には、AWS でのエラー再試行とエクスポネンシャルバックオフOpens in new tabに記載の擬似コードを参照のこと。

認証管理

ガバメントクラウドへの移行に際して、利用者の認証が必要なアプリケーションにおいては、独自の認証プロトコルではなく標準仕様として定義されている方式にしたがったシステムの実装が求められる場合がある。職員認証サービス(GIMA)やガバメントソリューションサービス(GSS)は、OpenID Connect(OIDC)の標準仕様に準拠した OpenID Provider(OP)の機能を提供している。アプリケーション側では、OIDC の標準仕様に対応することで、ID やパスワードの認証情報の管理が不要になり、同一の OP と連携する他システムとのシングルサインオンが可能になるメリットがある。

OIDC では、認証のフローとして複数の方式が定義されており、本節では、その中の Authorization Code Flow を例に取ってシステム側で対応が必要になる項目の概要を説明する。下図が、Authorization Code Flow の処理の一般的な流れを示したものである。OIDC のフローにおいて、認可を要求するアプリケーションは Relying Party(RP) と呼ばれる。

Authorization Code Flow概要
図 1. Authorization Code Flow 概要

OIDC でサポートされているその他の方式等については OIDC の仕様書であるOpenID Connect Core 1.0 日本語訳Opens in new tabを参照のこと。

Authorization Code Flow の中で、RP として実装が必要になる項目は以下の通り。

項目処理の概要
認可リクエストの生成ユーザが未ログイン状態であるなどの認証が必要な場合に、OP への認証リクエストを生成し、クライアント端末にログインを指示する
認可コードの受信ログインの成功後に、 OP から発行された認可コードを受信する。そして、OP へ認可コードを送信し、トークン(ID トークン及びアクセストークン)を取得する
アクセス可否の判断OP から取得したトークン(ID トークン及びアクセストークン)から、ログインしたユーザの属性情報を取得し、システムへのアクセスの可否を判断する

また、RP として必要になる設定として、OP に対するクライアントの登録を行うことが挙げられる。さらに、Webアプリケーション等のクライアントタイプ「confidential」においては、クライアントシークレットを発行しておく必要がある。

静的 Web サイト

HTML や Javascript 等を配信する静的 Web サイトに対しては、S3 と CloudFront を使用した構成に変更することも有効である。

例えば、仮想マシン上の Apache や nginx 等の Web サーバで静的 Web サイトを公開する場合は、公開するファイルを保管するストレージコストが必要になり、さらに、静的 Web サイトへのアクセスが増加した場合の考慮も必要となる。一方、S3 と CloudFront を利用した構成の場合は、S3 の利用によりストレージコストが抑えられ、静的 Web サイトへのアクセスが増加した場合も、CloudFront のキャッシュの利用により、高いパフォーマンスが期待できる。

S3 と CloudFront を使用した構成についてはCloudFront を使用して、Amazon S3 でホストされた静的ウェブサイトを提供するにはどうすればよいですか?Opens in new tabを参照のこと。

改訂履歴

改訂年月日改訂理由
2023 年 03 月 27 日新規作成
2023 年 11 月 02 日クライアントタイプ「confidential」に関するRPの設定内容を修正
2023 年 12 月 22 日「Elastic Load Balancing」の誤字を修正