💻

実務レベルのAWS Webアプリ構築ハンズオン

に公開

AWS構成図

こんにちは、フリーランスエンジニアのたいち(@taichi_hack_we)です。
今回は前回の記事↓で作成したKotlin、Spring BootバックエンドAPIを使って上記の実務レベルAWS構成でWebアプリを構築していきます。

https://zenn.dev/taichi_hack_we/articles/84c623ebee9e86

検証環境、本番環境アカウントを用意して1ユーザーアカウントでログインできるようにする

下記記事にそって、1つのIdentity Centerユーザーアカウントで検証環境と本番環境それぞれのAWSアカウントにログインできるようにしましょう。検証、本番アカウントを分ける理由は全環境を1つのアカウントで構築すると各環境のAWSリソースが混在して管理が面倒だからです。

また環境ごとにユーザID、パスワード、多要素認証を用意するのが手間なので、1ユーザアカウントで各環境のAWSアカウントにログインできるようにします。

https://techblog.ap-com.co.jp/entry/2024/04/11/090357

以下の内容で設定してください。

  • Identity Centerユーザー
    • ユーザー名:任意の値 ex.taichi
    • 多要素認証:ON
  • AWS Organizationsの検証環境用AWSアカウント
    • AWSアカウント名:aws-practice-stg
    • IAMロール名:OrganizationAccountAccessRole(デフォルトのまま)
  • AWS Organizationsの本番環境用AWSアカウント
    • AWSアカウント名:aws-practice-prd
    • IAMロール名:OrganizationAccountAccessRole(デフォルトのまま)
  • AWS Organizationsの組織構造:Root > aws-practice > aws-practice-prdとaws-practice-stg
  • Identity Centerの検証環境用許可セット
    • ポリシー:AdministratorAccess
    • 許可セット名:aws-practice-stg
  • Identity Centerの本番環境用許可セット
    • ポリシー:AdministratorAccess
    • 許可セット名:aws-practice-prd
  • Identity Centerの検証環境用AWSアカウントへのユーザー、許可セット割り当て
    • ユーザー:Identity Centerで作成したユーザー ex.taichi
    • 許可セット:aws-practice-stg
  • Identity Centerの本番環境用AWSアカウントへのユーザー、許可セット割り当て
    • ユーザー:Identity Centerで作成したユーザー ex.taichi
    • 許可セット:aws-practice-prd

検証、本番の許可セットポリシーが同じAdministratorAccessなのに検証、本番で許可セットをそれぞれ用意している理由は、ログイン後のAWSマネジメントコンソールで許可セット名が表示されるためです。aws-practice-stgのように許可セット名に環境名が含まれていれば、自分が今いる環境がひと目でわかります。

AWSマネジメントコンソールのユーザー表示

上記の設定が完了すると以下手順で各環境にログインできるようになります。

  1. https://{固有のID}.awsapps.com/start/#/?tab=accountsでAWS access portalへアクセス
  2. ユーザID、パスワードでログイン
  3. AWS access portalから好きな環境へ入る

ユーザログイン画面

AWS access portal

環境を切り替えたいときは再度AWS access portalから好きな環境へ入ります。

aws-practice-stgアカウントのリージョンを東京にする

aws-practice-stgにログインしたら、最初に画面右上から東京 ap-northeast-1リージョンを選択します。

東京リージョンを選択

以降のAWSリソースは特に記載がない限り東京リージョンで作成してください。

AWS CLIを使えるようにする

AWS環境構築でAWS CLIを使う場面があるので設定します。

AWS CLI用のIAMユーザー作成

以下の設定でAWS CLI用のIAMユーザーを作成しましょう。

  • ユーザー名:aws-practice-terraform-stg
  • AWS マネジメントコンソールへのユーザーアクセスを提供する:チェックなし
  • 許可ポリシー:AdministratorAccess

AWS CLI用のIAMユーザー設定

ユーザー名がaws-practice-terraform-stgなのは、これから構築するAWS構成をTerraform管理するときにも使うユーザーだからです。マネジメントコンソールへのアクセスはセキュリティのために提供しません。さまざまなAWSリソースを扱うのでAdministratorAccess権限を設定します。

IAMユーザーのアクセスキー作成

自分のPCからAWSリソースへアクセスするためのアクセスキーを作成します。

アクセスキー作成ボタン

ユースケースにコマンドラインインターフェースを選択し、アクセスキーのcsvファイルをダウンロードして完了をしましょう。csvファイルはIAMユーザーを使うために必要なので保管してください。

AWS CLIの設定

ACS CLIのインストール

AWS CLIのインストールは公式ドキュメントの手順でも良いのですが、homebrewを使えば以下のコマンドで一発です。

brew install awscli

インストールが成功すれば以下のコマンドが実行できます。

aws --version

aws-cli/2.24.27 Python/3.12.9 Darwin/24.4.0 source/arm64

バージョンアップやアンインストールもhomebrewで簡単にできます。

AWS CLI設定ファイルの作成

aws configureコマンドで対話形式でAWS CLIの設定ファイルを作成できます。以下の設定をしましょう。

aws configure

AWS Access Key ID [None]: アクセスキーのcsvファイルのAccess key ID
AWS Secret Access Key [None]: アクセスキーのcsvファイルのSecret access key
Default region name [None]: ap-northeast-1
Default output format [None]: json

設定が完了すると~/.aws/credentials~/.aws/configの2つのファイルが作成されます。

~/.aws/credentialsの更新

credentialsファイルを開きます。

code ~/.aws/credentials
credentials
[default]
aws_access_key_id = アクセスキーのcsvファイルのAccess key ID
aws_secret_access_key = アクセスキーのcsvファイルのSecret access key

credentialsはIAMユーザーのアクセスキーを管理するファイルです。AWS CLIで使いたいユーザーやアクセスキーが増えたらcredentialsに追記します。

[default]はデフォルトで使われるユーザーなので、わかりやすく[aws-practice-terraform-stg]に更新しましょう。

~/.aws/configの更新

configファイルを開きます。

code ~/.aws/config
config
[default]
region = ap-northeast-1
output = json

configにはリージョンとAWS CLIの出力形式が管理されています。config[default][profile aws-practice-terraform-stg]に更新しましょう。これでcredentialsaws-practice-terraform-stgconfig[profile aws-practice-terraform-stg]がひも付きます。

AWS CLIの動作確認

AWS_PROFILEという環境変数にcredentialsで設定したユーザー名を設定すると、AWS CLIがcredentialsconfigの内容を読み込みます。

export AWS_PROFILE=aws-practice-terraform-stg

AWS_PROFILEの設定ができたら以下のコマンドでAWS CLIが使えるか試しましょう。

aws iam list-users --output table

-------------------------------------------------------------------------------
|                                  ListUsers                                  |
+-----------------------------------------------------------------------------+
||                                   Users                                   ||
|+------------+--------------------------------------------------------------+|
||  Arn       |  arn:aws:iam::{ユーザーID}:user/aws-practice-terraform-stg   ||
||  CreateDate|  2025-05-06T02:00:18+00:00                                   ||
||  Path      |  /                                                           ||
||  UserId    |  ユーザーID                                                  ||
||  UserName  |  aws-practice-terraform-stg                                  ||
|+------------+--------------------------------------------------------------+|

AWS_PROFILEの自動設定

direnvでaws-practiceディレクトリではAWS_PROFILE=aws-practice-terraform-stgが環境変数として自動設定されるようにします。direnvについて詳しく知りたい方は以下の記事を参考にしてください。

https://zenn.dev/masuda1112/articles/2024-11-29-direnv

まずはaws-practiceディレクトリでdirenvの設定をします。

cd {aws-practiceへのパス}
direnv allow

作成されたaws-practice/.envrcに以下を追記しましょう。

export AWS_PROFILE=aws-practice-terraform-stg

再度direnv allowで追記した内容を使えるようにします。その後、別のディレクトリから再度aws-practiceディレクトリへ移動し、環境変数が自動設定されるか確認しましょう。

cd ..
cd aws-practice
echo $AWS_PROFILE

aws-practice-terraform-stgが表示されればOKです。

VPC作成

AWSのプライベートなネットワークであるVPCを作成します。設定内容は以下のとおり。

VPCの設定

IPv4 CIDRは10.0.0.0/16がネットワーク部が最も小さくなる設定値です。ネットワーク部を最小にすることで、VPC内により多くのIPアドレスを作成できます。

複数のVPCが必要な場合や小規模なサービスの場合は、ネットワーク部を大きく設定します。ネットワーク部を大きくするとIPアドレス空間が小さくなって攻撃対象領域が減ります。

VPCが作成できたら編集から

  • DNS解決を有効化
  • DNSホスト名を有効化

のチェックをONにしてください。

VPCのDNS設定

DNSホスト名が有効化されていないと、VPC内のAWSリソースにホスト名が付与されません。するとECSタスクが別のECSタスクと通信時に名前解決ができないといった障害が起こります。

サブネット作成

作成したVPC内に4つのサブネットを作成します。

  • public-subnet-1a-stg
    • アベイラビリティゾーン:ap-northeast-1a
    • IPv4 VPC CIDRブロック:10.0.0.0/18
  • public-subnet-1c-stg
    • アベイラビリティゾーン:ap-northeast-1c
    • IPv4 VPC CIDRブロック:10.0.64.0/18
  • private-subnet-1a-stg
    • アベイラビリティゾーン:ap-northeast-1a
    • IPv4 VPC CIDRブロック:10.0.128.0/18
  • private-subnet-1c-stg
    • アベイラビリティゾーン:ap-northeast-1c
    • IPv4 VPC CIDRブロック:10.0.192.0/18

サブネットの設定

VPCの10.0.0.0/16を4つのサブネットに分割する計算は以下のとおり。

  1. VPC内のIPアドレス数は2^16=65536
  2. 4サブネットに分割するので1サブネットのIPアドレス数は65536/4=16384
  3. 1サブネットのIPアドレス数が16384=2^14なので、サブネットのCIDRは/18
  4. VPCのCIDR/16とサブネットの/18の差分は2。2ビットでの2進数は00、01、10、11
  5. 第3オクテットの1、2ビット目が00、01、10、11なので10進数に直すと0、64、128、256

インターネットゲートウェイ作成

パブリックサブネットのAWSリソースをインターネットにつなげるためにはインターネットゲートウェイが必要です。aws-practice-igw-stgという名前タグで作成してください。

インターネットゲートウェイの作成

作成したインターネットゲートウェイをVPCaws-practice-stgにアタッチしましょう。

インターネットゲートウェイのVPCアタッチ

NATゲートウェイについて理解する

役割と使用例

NATゲートウェイはサブネットから外への通信のみ許可します。許可された通信のresponseも許可されます。ですがインターネットゲートウェイと違い、外からサブネットへの通信は許可されません

なのでプライベートサブネットのAWSリソースのセキュリティを保ちつつ、サブネット外と通信したいときに使います。たとえばプライベートサブネットのECSタスクがNAT経由でECRにアクセスするといった使い方ができます。

コスト対策

NATゲートウェイは1時間あたり$0.062、処理データ1GBあたり$0.062のコストがかかります。1ドル150円で計算すると、つけっぱなしで処理データが0でも月7000円弱の費用です。

個人利用で月7000円はキツいので、本記事ではコストが10分の1ほどになるNATインスタンスを使います。他のコスト対策として、難易度は上がりますがVPC Endpointを使う方法もあります。

NATゲートウェイの設定例

実務で扱えるようになるため、NATゲートウェイの設定を理解しましょう。本記事のAWS構成でNATゲートウェイを使う場合、以下の設定になります。

  • 名前:aws-practice-nat-1a
  • サブネット:public-subnet-1a-stg
  • 接続タイプ:パブリック
  • Elastic IP割り当てID:あり
  • タグ:Name aws-practice-nat-1a(自動入力される)

NATゲートウェイの設定

プライベートサブネットのAWSリソースのインターネット接続が目的の場合、NATゲートウェイはパブリックサブネットに配置します。通信がプライベートサブネット → NAT → インターネットの順に流れるためです。
またElastic IPの割り当ても必須です。インターネット通信のためにはパブリックなIPアドレスが必要だからです。

AWSのベストプラクティスは複数AZでの冗長化推奨

NATゲートウェイはAZ内で冗長化されているので、使っているNATで障害が起きてもシステムを維持できます。ただAZ障害が起こるとプライベートサブネットのAWSリソースは全てNATを介した通信ができなくなります。そのためAWSのベストプラクティスとして複数AZでのNAT冗長化が推奨されています。

NATインスタンス作成

セキュリティグループ作成

NATインスタンス用のセキュリティグループを作成します。以下のようにプライベートサブネットからのインバウンド通信を許可します。

  • セキュリティグループ名:aws-practice-nat-stg
  • 説明:Managed by Terraform
  • VPC:aws-practice-stg
  • インバウンドルール1つめ
    • タイプ:すべてのトラフィック
    • ソース:カスタム 10.0.128.0/18(private-subnet-1a-stgのIP)
  • インバウンドルール2つめ
    • タイプ:すべてのトラフィック
    • ソース:カスタム 10.0.192.0/18(private-subnet-1c-stgのIP)
  • アウトバウンドルール(デフォルト)
    • タイプ:すべてのトラフィック
    • 送信先:カスタム 0.0.0.0/0

NATインスタンスのセキュリティグループ

NATインスタンスにSession ManagerでアクセスするためのIAMロールを設定

AmazonSSMManagedInstanceCoreポリシーを持ったIAMロールを作成します。このロールはあとでNATインスタンスに設定します。

AmazonSSMManagedInstanceCoreポリシーを持ったIAMロールが必要な理由はNATインスタンスにSession Managerで接続するのに必要だからです。IAMロールの設定内容は以下のとおり。

  • 信頼されたエンティティタイプ:AWSのサービス
  • サービスまたはユースケース:EC2
  • 許可ポリシー:AmazonSSMManagedInstanceCore
  • ロール名:aws-practice-nat-stg

NATインスタンス用のIAMロール設定1

NATインスタンス用のIAMロール設定2

NATインスタンス用のIAMロール設定3

EC2インタンス作成

NATインスタンスとして使うEC2インスタンスを以下設定で作成します。

  • 名前:aws-practice-nat-1a-stg
  • AMI:Amazon Linux 2023 AMI
  • アーキテクチャ:64ビット(x86)
  • インスタンスタイプ:t2.micro
  • VPC:aws-practice-stg
  • サブネット:public-subnet-1a-stg
  • パブリックIPの自動割り当て:有効化
  • セキュリティグループ:aws-practice-nat-stg
  • IAMインスタンスプロフィール:aws-practice-nat-stg

NATインスタンス用のEC2インスタンス設定1

NATインスタンス用のEC2インスタンス設定2

NATインスタンス用のEC2インスタンス設定3

IAMインスタンスプロフィールでSession ManagerでアクセスするためのIAMロールを使っています。EC2インスタンスに直接IAMロールは紐づけられません。代わりにIAMロールが入ったIAMインスタンスプロフィールを紐づけます。

また未使用時にNATインスタンスを停止すればコスト削減ができます。

実務でNATインスタンスを使う場合、Elastic IPをつけるのが一般的です。インスタンス起動のたびにIPアドレスが変わると運用に影響が出るためです。ただ本記事ではコスト削減のためにElastic IPをつけません。

Session Managerによる接続確認

EC2インスタンスが実行中になったら、Session Managerで接続できるか確認してください。以下のような画面が表示できればOKです。

Session Managerの接続画面

EC2でNATの設定をする

EC2をNATとして動かすため、Session ManagerでEC2に入り、以下の記事にそって設定をしてください。

実施するのは、

  • NAT AMIを作成する
  • 送信元/送信先チェックを無効にする

の手順です。

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/work-with-nat-instances.html#create-nat-ami

NATの設定ができたら設定済のEC2からAMIを作成します。本番環境のNATインスタンスで使うためです。設定内容は以下のとおり。

AMI作成の設定

NATインスタンスの動作確認

NATインスタンスの動作確認は参考記事のNATインスタンスをテストするの手順でできます。

また本記事の後半で書いているECSタスクの起動が正常にできれば、NATインスタンスの動作確認にもなります。ECSタスクの起動時はECRからのDockerイメージ取得などの外部通信が発生するからです。

ルートテーブル作成

プライベートサブネット用

以下設定でルートテーブルを作成します。

  • 名前:aws-practice-rtb-private-stg
  • VPC:aws-practice-stg

ルートテーブル作成

そして0.0.0.0/0をNATインスタンスに向けたルートを追加します。

ルートテーブルのルートにNATインスタンス追加

作成したルートテーブルをプライベートサブネットに関連付けましょう。

ルートテーブルとプライベートサブネットを関連付ける

作成したプライベートサブネット用ルートテーブルをメインルートテーブルにしておくと、サブネット作成時のデフォルトルートテーブルになります。サブネットとルートテーブル関連付けを忘れても通信がインターネットに向かないので安全です。

メインルートテーブルの設定

パブリックサブネット用

以下設定でルートテーブルを作成します。

  • 名前:aws-practice-rtb-public-stg
  • VPC:aws-practice-stg

そして0.0.0.0/0インターネットゲートウェイに向けたルートを追加します。

ルートテーブルのルートにインターネットゲートウェイ追加

作成したルートテーブルをパブリックサブネットに関連付けましょう。

ルートテーブルとパブリックサブネットを関連付ける

RDS作成

RDSに必要なAWSリソースを作成します。

セキュリティグループ

セキュリティグループ設計のベストプラクティス

セキュリティグループ設計は1サービス1セキュリティグループがベストプラクティスです。1サービス1セキュリティグループはシンプルでわかりやすく、どこからの通信を許可しているのかひと目でわかります。

たとえば、

  • WebサーバーEC2とWebサーバーEC2用セキュリティグループ
  • RDSとRDS用セキュリティグループ

があるとします。この状態でRDS用セキュリティグループのインバウンドルールにWebサーバー用EC2セキュリティグループのみが設定されていれば、RDSはWebサーバーからの通信のみ許可していることがすぐ理解できます。

1つのサービスに1つのセキュリティグループがわかりやすく運用しやすい設計です。

作成

以下設定でRDS用のセキュリティグループを作成します。

  • セキュリティグループ名:aws-practice-db-stg
  • 説明:Managed by Terraform(今後Terraformで設定する値をあらかじめ登録)
  • VPC:aws-practice-stg
  • インバウンドルール:なし
  • アウトバウンドルール:すべてのトラフィックで0.0.0.0/0(デフォルト設定)

RDSのセキュリティグループ設定

RDSはAPIサーバーからの通信のみを許可します。ですが、現時点でAPIサーバーはないのでインバウンドルールを一旦なしで設定します。

DBサブネットグループ

複数AZにまたがるサブネットをDBサブネットグループとして指定することで、DBが障害時にフェイルオーバーするので冗長性が高まります。作成するDBサブネットグループは以下です。

  • 名前:aws-practice-db-subnet-group-stg
  • 説明:Managed by Terraform
  • VPC:aws-practice-stg
  • サブネット:private-subnet-1a-stg、private-subnet-1c-stg

DBサブネット設定

DBは外部からアクセスされたくないので、プライベートサブネットを指定します。

パラメータグループ

RDSのパラメータグループでデータベースの設定を簡単に作成できます。以下の設定で作成しましょう。

  • パラメータグループ名:aws-practice-db-parameter-group-stg
  • 説明:Managed by Terraform
  • エンジンのタイプ:PostgreSQL
  • パラメータグループファミリー:postgres17
  • タイプ:DB Parameter

RDS

以下設定でRDSを作成します。

RDS設定1

RDS設定2

RDS設定3

RDS設定4

RDS設定5

RDS設定6

RDS設定7

RDS設定8

RDS設定9

RDS設定10

RDS設定11

RDSは未使用時に停止すればコスト削減ができます。ですが7日間で自動起動してしまいます... なので後でEvent Bridge Schedulerを使って7日ごとに起動 → 停止するよう設定します。

Secrets Managerで機密性のある環境変数を管理

DBのユーザーやパスワードなど、機密性のある環境変数はSecrets Managerで管理します。以下設定でシークレットを作成しましょう。

  • シークレットのタイプ:その他のシークレットのタイプ
  • キー/値のペア
    • DB_HOST:作成したRDSのエンドポイント(例aws-practice-stg{固有の文字列}amazonaws.com)
    • DB_PORT:5432
    • DB_NAME:aws_practice
    • DB_USER_NAME:RDS作成後に確認したマスターユーザー名
    • DB_PASSWORD:RDS作成後に確認したマスターパスワード
  • 暗号化キー:aws/secretsmanager
  • シークレットの名前:rds-main-stg
  • 自動ローテーション:OFF

RDSのデフォルトユーザーをそのまま使うのは権限が強すぎてセキュリティ上良くないので、後で新しいユーザーを作成してSecrets Managerの設定値を更新します。

ECR

前回の記事で作成したバックエンドAPIのDockerイメージをpushするECRリポジトリを作成し、pushしてみます。

プライベートリポジトリ作成

設定内容は以下のとおり。

  • リポジトリ名:aws-practice-stg
  • イメージタグのミュータビリティ:Immutable
  • 暗号化設定:AES-256

ECRの設定

タグはImmutableにしてコミットハッシュを使うのがセキュリティ的にも運用的にもベストプラクティスです。詳しくは以下の記事が参考になります。

https://zenn.dev/levtech/articles/8feb6330f7c767

ライフサイクルポリシー設定

ECRにpushしたイメージがたまっていくとコストがかさみます。なので最新3つのイメージのみ保持するよう、以下設定でaws-practice-stgのライフサイクルポリシーを作成します。

  • ルールの優先順位:1
  • ルールの説明:最新3つのイメージのみ保持
  • イメージのステータス:すべて
  • 一致条件:次の数値を超えるイメージ数 3

バックエンドAPIのDockerイメージをECRへpush

前回の記事のデータベース環境構築のところで扱ったMakefileを使ってECRへログイン、Dockerイメージbuild、ECRへのpushをします。

https://github.com/taichi-web-engineer/aws-practice/blob/main/Makefile

MakefileのAWSアカウント情報更新

Makefileの以下の箇所は私のAWSアカウントIDになっているので、自身のアカウントIDに更新してください。

# AWS_ACCOUNT_IDを自身の情報に更新する
AWS_ACCOUNT_ID ?= 355195805635

aws-practiceプロジェクトのルートへ移動

cd {aws-practiceへのパス}

aws-practiceへ移動すればdirenvでAWS CLIの設定が自動適用されます。

ECRログイン

ECRにログインするコマンドはmake docker-login ENV=stgで、実態は以下のコマンドです。

# ECRにログインする
# e.g. make docker-login ENV=stg ECR_NAME=aws-practice
docker-login: .check-env .check-ecr-name
	aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${IMAGE_REPOSITORY_URI}

このECRログインコマンドはaws-practice-stgのECRリポジトリのプッシュコマンドを表示ボタンで確認できます。これから実行するDockerイメージbuild、ECRへのpushコマンドもここに書いてあるものを元に作成しています。

ECRのコマンド

ECRログインコマンドを実行して以下の表示が出ればOKです。

make docker-login ENV=stg
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 355195805635.dkr.ecr.ap-northeast-1.amazonaws.com/aws-practice-stg
Login Succeeded

Dockerイメージをbuild

Dockerイメージbuildのコマンドはmake build-image ENV=stg DOCKERFILE_DIR=./apiで、実態は以下です。

# Dockerイメージをビルドする
# e.g. make build-image ENV=stg
# Fargateで動かすならplatformはlinux/arm64の方が安いが、Github Actionsの有料プランでしかarm64が使えないためlinux/amd64を指定
build-image: .check-env .check-ecr-name
	docker build --platform=linux/amd64 -t ${IMAGE_REPOSITORY_URI}:${GIT_COMMIT_HASH} -f ${DOCKERFILE_DIR}/Dockerfile ${DOCKERFILE_DIR}

buildコマンドを実行してエラーが出なければOKです。

ECRへpush

buildしたDockerイメージのpushコマンドはmake push-image ENV=stgで、実態は以下です。

# DockerイメージをECRにpushする
# e.g. make push-image ENV=stg
push-image: .check-env .check-ecr-name
	docker push ${IMAGE_REPOSITORY_URI}:${GIT_COMMIT_HASH}

pushが成功するとaws-practice-stgのリポジトリでpushしたDockerイメージを確認できます。

ECRへのpush結果

ECRログイン、Dockerイメージbuild、ECRへpushを一括実行

make release-image ENV=stg DOCKERFILE_DIR=./apiでECRログイン、Dockerイメージbuild、ECRへpushを一括実行できます。

# DockerイメージをビルドしてECRにpushする
# e.g. make release-image ENV=stg
release-image: docker-login build-image push-image

(続きは随時更新します)

Discussion