AWSコンソール マニュアル Web Application Baseline Manual
このランブックは、AWSコンソールで1つのWebアプリケーションのベースラインAWSインフラを構築します。リージョン: ap-northeast-1(アジアパシフィック - 東京)。
ターゲットアーキテクチャ
AWSコンソールにおける単一Webアプリケーションのベースラインインフラ構成。
| コンポーネント | 設定内容 |
|---|---|
| リージョン | ap-northeast-1 (アジアパシフィック - 東京) |
| コンピューティング | パブリックサブネット内の1つのUbuntu Server 24.04 LTS EC2インスタンス |
| パブリックアクセス | EC2に直接関連付けられたElastic IP。TCP 22, 80, 443のインバウンドを許可 |
| データベース | パブリックサブネット内のパブリックアクセス可能なAmazon RDS for PostgreSQL 16。TCP 5432を開放 |
| オブジェクトストレージ | 1つのS3バケット。public/* のみ匿名読み取り可能 |
| Eメール | Amazon SESで検証されたアイデンティティとSMTP資格情報 |
| ロードバランサー | 本ベースラインには含まれません。複数インスタンスやマネージドTLS終端が必要な場合のみALBを追加してください。 |
作業開始前に決定する値
myapp-prod のような一貫したアプリケーション接頭辞を使用してください。
| 項目 | 例 / 必須値 |
|---|---|
| アプリケーション接頭辞 | <APP> |
| VPC CIDR | <VPC_CIDR> |
| パブリックサブネットCIDR | <PUBLIC_SUBNET_A_CIDR> , <PUBLIC_SUBNET_C_CIDR> |
| EC2インスタンスタイプ | <EC2_INSTANCE_TYPE> |
| EBSルートボリュームサイズ | <EBS_GIB> GiB |
| DBインスタンスクラスおよびストレージ | <DB_INSTANCE_CLASS>, <DB_STORAGE_GIB> GiB initial, <DB_MAX_STORAGE_GIB> GiB maximum |
| データベース名 | <DB_NAME> |
| SSH接続元CIDR | <SSH_SOURCE_CIDR> ; 0.0.0.0/0 |
| 一意のS3バケット名 | <GLOBALLY_UNIQUE_BUCKET_NAME> |
| SES送信ドメインまたはEメール | <SENDING_IDENTITY> |
必要なコンソール権限
作業を開始する前に、クライアントから提供されたIAMユーザーに以下の3つのインラインポリシーを付与します。これらは構築作業およびAWSコンソール表示に必要な権限をカバーします。<APP>-infrastructure-provisioning, <APP>-iam-provisioning, <APP>-ses-support-provisioning として作成します。<ACCOUNT_ID>、<APP>、<PROVISIONING_IAM_USER>、<GLOBALLY_UNIQUE_BUCKET_NAME> を先に置き換えてください。
これらは構築用ポリシーであり、アプリケーション用ポリシーではありません。ap-northeast-1でのリソース作成のみを許可します(IAMおよびS3などのグローバルサービスを除く)。一部の作成アクションはリソースレベルの権限をサポートしていないため、それらのリソースは * のままにする必要があります。引き継ぎ完了後に削除してください。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "cloudwatch:GetMetricData",
"Resource": "*",
"Condition": {
"StringEquals": { "aws:RequestedRegion": "ap-northeast-1" }
}
},
{
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"ec2:GetConsole*",
"rds:Describe*",
"rds:ListTagsForResource"
],
"Resource": "*",
"Condition": {
"StringEquals": { "aws:RequestedRegion": "ap-northeast-1" }
}
},
{
"Effect": "Allow",
"Action": [
"s3:GetAccountPublicAccessBlock",
"s3:ListAllMyBuckets"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:GetBucket*",
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::<GLOBALLY_UNIQUE_BUCKET_NAME>"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::<GLOBALLY_UNIQUE_BUCKET_NAME>/*"
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateVpc",
"ec2:ModifyVpcAttribute",
"ec2:CreateSubnet",
"ec2:ModifySubnetAttribute",
"ec2:CreateInternetGateway",
"ec2:AttachInternetGateway",
"ec2:CreateRouteTable",
"ec2:AssociateRouteTable",
"ec2:CreateRoute",
"ec2:CreateSecurityGroup",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:CreateTags"
],
"Resource": "*",
"Condition": {
"StringEquals": { "aws:RequestedRegion": "ap-northeast-1" }
}
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateKeyPair",
"ec2:RunInstances",
"ec2:AllocateAddress",
"ec2:AssociateAddress",
"ec2:ModifyVolume",
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:RebootInstances",
"ec2:CreateTags"
],
"Resource": "*",
"Condition": {
"StringEquals": { "aws:RequestedRegion": "ap-northeast-1" }
}
},
{
"Effect": "Allow",
"Action": [
"kms:DescribeKey",
"kms:ListAliases"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "kms:CreateGrant",
"Resource": "arn:aws:kms:ap-northeast-1:<ACCOUNT_ID>:key/*",
"Condition": {
"ForAnyValue:StringEquals": {
"kms:ViaService": [
"ec2.ap-northeast-1.amazonaws.com",
"rds.ap-northeast-1.amazonaws.com"
]
},
"Bool": { "kms:GrantIsForAWSResource": "true" }
}
},
{
"Effect": "Allow",
"Action": [
"kms:DescribeKey",
"kms:GenerateDataKeyWithoutPlaintext"
],
"Resource": "arn:aws:kms:ap-northeast-1:<ACCOUNT_ID>:key/*",
"Condition": {
"ForAnyValue:StringEquals": {
"kms:ViaService": [
"ec2.ap-northeast-1.amazonaws.com",
"rds.ap-northeast-1.amazonaws.com"
]
}
}
},
{
"Effect": "Allow",
"Action": [
"rds:CreateDBSubnetGroup",
"rds:CreateDBParameterGroup",
"rds:CreateDBInstance",
"rds:ModifyDBParameterGroup",
"rds:ModifyDBInstance",
"rds:StartDBInstance",
"rds:StopDBInstance",
"rds:RebootDBInstance",
"rds:AddTagsToResource"
],
"Resource": "*",
"Condition": {
"StringEquals": { "aws:RequestedRegion": "ap-northeast-1" }
}
},
{
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:PutBucketOwnershipControls",
"s3:PutBucketVersioning",
"s3:PutEncryptionConfiguration",
"s3:PutBucketPublicAccessBlock",
"s3:PutBucketPolicy",
"s3:PutBucketCors"
],
"Resource": [
"arn:aws:s3:::<GLOBALLY_UNIQUE_BUCKET_NAME>",
"arn:aws:s3:::<GLOBALLY_UNIQUE_BUCKET_NAME>/*"
]
}
]
}AWSマネージドポリシーによる代替案
上記のインラインポリシーの維持が1回限りのセットアップに対して過剰な場合、一時的に以下のAWSマネージドポリシーをアタッチできます:
| 手動ワークフロー | 対応するAWSマネージドポリシー |
|---|---|
| VPC、サブネット、ルートテーブル、セキュリティグループ | AmazonVPCFullAccess |
| キーペア、EC2インスタンス、EBS、Elastic IP | AmazonEC2FullAccess |
| RDSサブネットグループ、パラメータグループ、データベース | AmazonRDSFullAccess |
| S3バケット、ポリシー、暗号化、バージョニング、CORS、オブジェクト管理 | AmazonS3FullAccess |
| アプリケーションIAMユーザー/アクセスキーおよびSES SMTP IAMユーザー | IAMFullAccess |
| IAM Access Analyzerによるポリシー検証 | IAMAccessAnalyzerFullAccess |
| RDSコンソールのメトリクス | CloudWatchReadOnlyAccess |
| SESアイデンティティと本番アクセスリクエスト | AmazonSESFullAccess |
| SESクォータ引き上げおよびAWSサポートケース起票 | ServiceQuotasFullAccess , AWSSupportAccess |
AdministratorAccessは便利な単一ポリシー代替案ですが、上記すべてを合わせたものより広い権限を持ちます。稼働中のアプリケーションに付与しないでください。引き渡し後にプロビジョニングユーザーからデタッチしてください。後で作成されるアプリケーションIAMユーザーは、以下に示すS3ポリシーのみを受け取ります。
インラインポリシーのKMS権限は、意図的にAWS管理ポリシーに置き換えられていません。アカウントがデフォルトのEBSおよびRDSキーの代わりにカスタマー管理KMSキーを必要とする場合、KMSキー管理者はKMSキーポリシーでこのユーザーも許可する必要があります。広範なKMS管理ポリシーをアタッチして補完しないでください。
RDS作成時に拡張モニタリングを有効にする場合は、Create new role を選択し、名前を `rds-monitoring-role` にします。信頼されたエンティティは `monitoring.rds.amazonaws.com` であり、`AmazonRDSEnhancedMonitoringRole` を使用する必要があります。IAMプロビジョニングポリシーは、その名前のロールのみを作成、読み取り、および渡し(pass)、そのAWS管理ポリシーのみをアタッチできます。
詳細権限マッピング
| 手動操作 | 対応する作成/設定権限 |
|---|---|
| VPC、サブネット、インターネットゲートウェイ、ルート、セキュリティグループ | ec2:CreateVpc , CreateSubnet , CreateInternetGateway , AttachInternetGateway , CreateRouteTable , AssociateRouteTable , CreateRoute , CreateSecurityGroup 、インバウンド/アウトバウンド許可、および必要なVPC/サブネット変更とタグ |
| SSHキーペア、EC2インスタンス/EBS、Elastic IP | ec2:CreateKeyPair , RunInstances , AllocateAddress , AssociateAddress , EBSリサイズ用 ModifyVolume , StartInstances , StopInstances , RebootInstances 、およびタグ |
| 暗号化されたEBSおよびRDSリソース | コンソールでデフォルトキーを確認。東京のEC2またはRDS経由のみでのグラントおよびデータキーの使用 |
| RDSサブネットグループ、パラメータグループ、データベース | サブネットグループ、パラメータグループ、DBインスタンスの作成。ストレージサイズを含む変更、起動・停止・再起動、リソースタグの追加、および未存在時のみのRDSサービス連動ロールの作成 |
| S3バケット、パブリックプレフィックスポリシー、CORS、オブジェクト管理 | s3:CreateBucket 、オブジェクト所有権、バージョニング、暗号化、パブリックアクセスブロック、バケットポリシー、CORS、および s3:GetObject , s3:PutObject , s3:DeleteObject |
| アプリケーションS3ユーザー/アクセスキーおよびSES SMTPユーザー | S3/SMTPユーザーとアクセスキーの作成。 <APP>-s3-bucket-access のみを作成して <APP>-s3-user にアタッチ。 AWSSESSendingGroupDoNotRename のみを作成・設定し、生成されたSMTPユーザーのみをそのグループに追加 |
| オプションのRDS拡張モニタリングロール | IAMユーザー/グループ/ロールおよびマネージドポリシーの作成・一覧表示。 rds-monitoring-role のみの読み取り・パス、および AmazonRDSEnhancedMonitoringRole のみのアタッチ |
| RDSコンソールのメトリクス | 東京リージョンでの cloudwatch:GetMetricData |
| SES設定セット、アイデンティティ、DKIM、本番アクセス | ses:CreateConfigurationSet , CreateEmailIdentity , PutEmailIdentityDkimAttributes 、および PutAccountDetails |
| SESクォータ引き上げおよびサポートケース起票 | Service Quotasの読み取り/リクエスト操作。AWS Supportケースの作成、閲覧、返信 |
1. ネットワークの作成
- ap-northeast-1 で VPC を開き、[VPC を作成] を選択します。
- [VPC など] を選択し、以下の設定を使用します:
| Setting | Value |
|---|---|
| Name tag auto-generation | <APP> |
| IPv4 CIDR block | <VPC_CIDR> |
| Number of Availability Zones | 2 |
| Number of public subnets | 2 |
| Public subnet CIDRs | <PUBLIC_SUBNET_A_CIDR> , <PUBLIC_SUBNET_C_CIDR> |
| Number of private subnets | 0 |
| NAT gateways | None |
| VPC endpoints | None (do not create an S3 endpoint) |
| DNS options | Keep Enable DNS hostnames and Enable DNS resolution selected |
- VPCを作成します。各パブリックルートテーブルに Internet Gateway への 0.0.0.0/0 ルートがあることを確認します。
- サブネットで、パブリックサブネットを <APP>-public-a および <APP>-public-c に名前変更します。
- 両方のサブネットで [パブリック IPv4 アドレスの自動割り当て] が有効であることを確認します。
セキュリティグループの作成
- EC2 > セキュリティグループ > セキュリティグループの作成 を開きます。
- <APP>-ec2-sg を作成し、インバウンドルール(SSH 22, HTTP 80, HTTPS 443)を設定します。
| Type | Protocol | Port | Source |
|---|---|---|---|
| SSH | TCP | 22 | <SSH_SOURCE_CIDR> |
| HTTP | TCP | 80 | 0.0.0.0/0 and ::/0 |
| HTTPS | TCP | 443 | 0.0.0.0/0 and ::/0 |
- デフォルトのアウトバウンドルール(全許可)を維持します。
- <APP>-rds-sg を作成し、PostgreSQL (TCP 5432, ソース 0.0.0.0/0) のインバウンドルールを追加します。
VPC ID、パブリックサブネットID、両方のセキュリティグループIDを記録します。
2. SSHキーペアの作成
- EC2 > キーペア で [キーペアを作成] を選択します。
- 名前を <APP>-ec2-key とし、ED25519 および .pem を選択して作成します。
- 秘密鍵をすぐにダウンロードし、所有者情報と復旧情報とともに承認されたシークレットストアに保存します。AWSは再ダウンロードできません。
キーペア名と .pem ファイルの保存場所を記録します。コードリポジトリにコミットしたり、共有ストレージに置いたりしないでください。
3. EC2の起動とElastic IPの割り当て
- EC2 > インスタンス で [インスタンスを起動] を選択します。
- インスタンス名を <APP>-web-1 とします。
- Ubuntu Server 24.04 LTS を選択します。
- <EC2_INSTANCE_TYPE>、<APP>-ec2-key キーペア、VPC <APP>-vpc を選択します。
- パブリックサブネットを選択し、<APP>-ec2-sg を選択します。
- ルートEBSボリュームを <EBS_GIB> GiB (gp3, 暗号化有効) に設定して起動します。
- ステータスチェックが通過したら、インスタンスIDを記録します。
- EC2 > Elastic IP > Elastic IP アドレスの割り当て でIPを取得します。
- <APP>-web-1 に Elastic IP を関連付けます。
インスタンスID、AZ、Elastic IP 割り当てID、IPアドレスを記録します。
4. RDSでPostgreSQL 16を作成
DBサブネットグループの作成
- RDS > サブネットグループ で作成します。
- <APP>-db-subnets と命名し、2つのAZのパブリックサブネットを追加します。
- サブネットグループを作成します。
パラメータグループの作成
- RDS > パラメータグループ で作成します。
- PostgreSQL, postgres16 ファミリーを選択し、<APP>-postgres16-parameters と命名します。
- パラメータグループを作成します。
- 編集で rds.force_ssl を 0 に変更して保存します。PostgreSQL 16はこのパラメータをデフォルトで 1 に設定しています。0 に設定すると非SSL接続が許可されます。
データベースの作成
- RDS > データベース > データベースの作成 を開きます。
- 標準作成、PostgreSQL、およびエンジンバージョン PostgreSQL 16 を選択します。
- 環境に応じたテンプレートを選択します。本番環境では、可用性の要件と予算が許す場合にのみマルチAZを有効にしてください。
- DBインスタンス識別子を <APP>-postgres16 に、マスターユーザー名を <DB_MASTER_USERNAME> に設定します。「パスワードを自動生成」を選択し、RDSに表示された生成済みマスターパスワードを承認されたシークレットストアにコピーします。このマニュアルやソース管理にパスワードを保存しないでください。
- DBインスタンスクラスを <DB_INSTANCE_CLASS> に設定します。ストレージで General Purpose SSD (gp3) を選択し、割り当てストレージを <DB_STORAGE_GIB> GiB に設定して、ストレージの暗号化を有効にします。ストレージの自動スケーリングを有効にし、予想される成長と予算に合わせて最大ストレージしきい値を <DB_MAX_STORAGE_GIB> GiB に設定します。
- 接続で、<APP>-vpc、<APP>-db-subnets、パブリックアクセス: あり、および既存のセキュリティグループ <APP>-rds-sg を選択します。デフォルトのセキュリティグループが自動的に追加された場合は削除します。
- 追加設定を展開し、DBパラメータグループとして <APP>-postgres16-parameters を選択します。アプリケーションで必要な場合は、最初のデータベース名を <DB_NAME> に設定します。
- 本番環境では自動バックアップと削除保護を有効にします。見積もりコストを確認し、データベースを作成します。
- 作成プロセスが終了し、DBインスタンスのステータスが利用可能になるまで待ちます。完了ページで「接続の詳細を表示」を選択し、エンドポイントとポートを記録します。完了ページを閉じてしまった場合は、DBインスタンスを開き、代わりに「接続とセキュリティ」タブを使用してください。
DB識別子、エンドポイント、ポート 5432、DB名、マスターユーザー名を記録します。
IAMポリシーに iam:CreateServiceLinkedRole が許可されていることを確認してください。
5. S3バケットとアプリケーション資格情報の作成
バケットの作成
- S3 > バケット で作成します。
- 名前を <GLOBALLY_UNIQUE_BUCKET_NAME> とし、ap-northeast-1 を選択します。
- オブジェクト所有権を [ACL無効] に維持します。
- アップロードの復元が必要な場合はバージョニングを有効のままにします。デフォルト暗号化を有効にします。
- [ブロックパブリックアクセス設定] で、パブリックバケットポリシーを妨げる設定のみ解除します: [新しいパブリックバケットポリシーまたはアクセスポイントポリシーを介してバケットとオブジェクトへのパブリックアクセスをブロックする] と [任意のパブリックバケットポリシーまたはアクセスポイントポリシーを介したバケットとオブジェクトへのパブリックアクセスおよびクロスアカウントアクセスをブロックする]。
- public/ 配下のオブジェクトが公開されることを確認してバケットを作成します。アカウントレベルのブロックパブリックアクセスが妨げる場合は、アカウント管理者がその設定を変更するかプライベート代替案を使用する必要があります。
パブリックプレフィックスバケットポリシーの追加
- バケットの [アクセス許可] タブ > [バケットポリシー] > [編集] を開きます。
- <GLOBALLY_UNIQUE_BUCKET_NAME> を置き換えてこのポリシーを保存します:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadOnlyForPublicPrefix",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<GLOBALLY_UNIQUE_BUCKET_NAME>/public/*"
}
]
}CORS ルールの追加
- バケットの [アクセス許可] タブ > [Cross-origin resource sharing (CORS)] > [編集] を開きます。
- この設定を保存します:
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
"AllowedOrigins": ["*"],
"ExposeHeaders": [],
"MaxAgeSeconds": 3000
}
]アプリケーションIAMユーザーの作成
- IAM > ユーザー > ユーザー作成 で <APP>-s3-user を作成します。
- マネジメントコンソールアクセスは無効にします。
- IAM > ポリシー > ポリシー作成 でJSONを入力します。
- バケット名を置き換え、<APP>-s3-bucket-access としてこのカスタマー管理ポリシーを作成します:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListThisBucketOnly",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::<GLOBALLY_UNIQUE_BUCKET_NAME>"
},
{
"Sid": "ManageObjectsInThisBucketOnly",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::<GLOBALLY_UNIQUE_BUCKET_NAME>/*"
}
]
}- <APP>-s3-user に戻り、[アクセス許可の追加] > [ポリシーを直接アタッチする] を選択し、<APP>-s3-bucket-access を選択してアクセス許可を追加します。
- ユーザーの [セキュリティ認証情報] タブ > [アクセスキーを作成] を開きます。求められた場合は [AWS の外部で実行されるアプリケーション] を選択し、確認を行ってキーを作成します。
- CSVをダウンロードするか、アクセスキーIDとシークレットアクセスキーを承認されたシークレットストアにコピーします。シークレットアクセスキーは一度のみ表示されます。
バケット名、ARN、ユーザーARN、アクセスキーIDを記録します。シークレットキーはチケット、チャット、またはソース管理に記録または送信しないでください。
6. Amazon SESの設定
- ap-northeast-1 の Amazon SES > アイデンティティの作成 を開きます。
- [ドメイン] を選択して <SENDING_IDENTITY> を入力します。SESが示すDNS検証レコードをドメインのDNSプロバイダーに追加します。DKIMを有効にしてすべてのDKIM CNAMEレコードを追加します。
- アイデンティティのステータスが [検証済み] になるまで待ちます。送信ドメインを検証できない場合のみ、メールアドレス形式のアイデンティティが使用できます。
- SESで [アカウントダッシュボード] を開き、[本番環境アクセスのリクエスト] を選択します。実際の送信ユースケース、ウェブサイト、メールの種類、予想送信量、バウンス/苦情処理、オプトアウトプロセスを記入します。未検証の受信者への送信前に承認を待ちます。
- [SMTP設定] > [SMTP認証情報の作成] を開きます。IAMユーザーを <APP>-ses-smtp と命名し、作成してSMTPユーザー名とパスワードをダウンロードします。
検証済みアイデンティティ、DNSレコード完了ステータス、SES本番アクセスステータス、ap-northeast-1のSMTPエンドポイント、SMTPユーザー名、SMTPパスワードのシークレットストア参照を記録します。
AWS Supportがユースケースを明確に確認できるよう、実用的な場合は英語で本番アクセスリクエストを送信してください。承認は、申請言語だけでなく、送信ユースケース、コンプライアンス、バウンス/クレーム処理情報の品質と正当性によって異なります。SMTP資格情報はリージョン固有です。S3 IAMアクセスキーとは別に保管し、アクセス権のあるオペレーターがプロジェクトを離れる際にローテーションしてください。
最終引き継ぎチェックリスト
インフラ引き継ぎ前のインタラクティブ確認項目
AWS アーキテクチャの設計・自動化をご検討ですか?
AIPROのシニアCloud & DevOpsエンジニアが、高信頼・低コスト・高セキュリティなインフラを構築します。
