{"id":3533,"date":"2026-10-14T11:29:19","date_gmt":"2026-10-14T02:29:19","guid":{"rendered":"https:\/\/qol-kk.com\/wp2\/?p=3533"},"modified":"2026-10-14T11:29:19","modified_gmt":"2026-10-14T02:29:19","slug":"20260912-00mtxn7z","status":"publish","type":"post","link":"https:\/\/qol-kk.com\/wp2\/blog\/2026\/10\/14\/20260912-00mtxn7z\/","title":{"rendered":"S3 \u3067\u9759\u7684 Web \u30b5\u30a4\u30c8\u3092\u30db\u30b9\u30c6\u30a3\u30f3\u30b0\u3059\u308b"},"content":{"rendered":"<h2>\u6982\u8981<\/h2>\n<p>HTML\/CSS\/JS \u3060\u3051\u3067\u5b8c\u7d50\u3059\u308b\u9759\u7684\u30b5\u30a4\u30c8\uff08\u30e9\u30f3\u30c7\u30a3\u30f3\u30b0\u30da\u30fc\u30b8\u3001\u88fd\u54c1\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3001SPA \u306e\u30d3\u30eb\u30c9\u6210\u679c\u7269\u306a\u3069\uff09\u306f\u3001\u30b5\u30fc\u30d0\u30fc\u3092\u7acb\u3066\u305a\u306b Amazon S3 \u3067\u30db\u30b9\u30c6\u30a3\u30f3\u30b0\u3067\u304d\u308b\u3002\u672c\u8a18\u4e8b\u3067\u306f\u6b21\u306e 2 \u30d1\u30bf\u30fc\u30f3\u3092\u30cf\u30f3\u30ba\u30aa\u30f3\u5f62\u5f0f\u3067\u69cb\u7bc9\u3059\u308b\u3002<\/p>\n<ol>\n<li><strong>S3 \u306e\u300c\u9759\u7684\u30a6\u30a7\u30d6\u30b5\u30a4\u30c8\u30db\u30b9\u30c6\u30a3\u30f3\u30b0\u300d\u6a5f\u80fd\u306b\u3088\u308b\u6700\u5c0f\u69cb\u6210<\/strong>\uff08\u5b66\u7fd2\u30fb\u691c\u8a3c\u5411\u3051\uff09<\/li>\n<li><strong>CloudFront + OAC\uff08Origin Access Control\uff09\u3067\u30d0\u30b1\u30c3\u30c8\u3092\u975e\u516c\u958b\u306e\u307e\u307e\u914d\u4fe1\u3059\u308b\u672c\u756a\u5411\u3051\u69cb\u6210<\/strong>\uff08HTTPS\u30fb\u72ec\u81ea\u30c9\u30e1\u30a4\u30f3\u5bfe\u5fdc\uff09<\/li>\n<\/ol>\n<p>\u7d50\u8ad6\u3068\u3057\u3066\u3001<strong>\u672c\u756a\u904b\u7528\u306a\u3089 2 \u3092\u9078\u3076<\/strong>\u30021 \u306f HTTPS \u306b\u5bfe\u5fdc\u305b\u305a\u3001\u30d0\u30b1\u30c3\u30c8\u3092\u516c\u958b\u8a2d\u5b9a\u306b\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u305f\u3081\u3060\u3002\u307e\u305a 1 \u3067\u4ed5\u7d44\u307f\u3092\u7406\u89e3\u3057\u3001\u305d\u306e\u3046\u3048\u3067 2 \u3078\u79fb\u884c\u3059\u308b\u6d41\u308c\u3067\u9032\u3081\u308b\u3002<\/p>\n<h2>\u74b0\u5883<\/h2>\n<ul>\n<li>AWS CLI v2\uff08<code>aws --version<\/code> \u3067\u78ba\u8a8d\uff09<\/li>\n<li>\u8a8d\u8a3c\u60c5\u5831\u304c\u8a2d\u5b9a\u6e08\u307f\uff08<code>aws configure<\/code> \u6e08\u307f\u3001\u307e\u305f\u306f SSO \u30ed\u30b0\u30a4\u30f3\u6e08\u307f\uff09<\/li>\n<li>\u30ea\u30fc\u30b8\u30e7\u30f3\u306f <code>ap-northeast-1<\/code>\uff08\u6771\u4eac\uff09\u3092\u4f8b\u306b\u4f7f\u7528<\/li>\n<li>\u30d0\u30b1\u30c3\u30c8\u540d\u306f\u5168\u4e16\u754c\u3067\u4e00\u610f\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308b\u305f\u3081\u3001\u672c\u8a18\u4e8b\u3067\u306f <code>example-static-site-20260912<\/code> \u306e\u3088\u3046\u306a\u30d7\u30ec\u30fc\u30b9\u30db\u30eb\u30c0\u3092\u4f7f\u3046<\/li>\n<\/ul>\n<h2>\u30d1\u30bf\u30fc\u30f31: S3 \u9759\u7684\u30a6\u30a7\u30d6\u30b5\u30a4\u30c8\u30db\u30b9\u30c6\u30a3\u30f3\u30b0\uff08\u6700\u5c0f\u69cb\u6210\uff09<\/h2>\n<h3>1. \u30d0\u30b1\u30c3\u30c8\u3092\u4f5c\u6210\u3059\u308b<\/h3>\n<pre class=\"lang:default decode:true\">aws s3api create-bucket \\\n  --bucket example-static-site-20260912 \\\n  --region ap-northeast-1 \\\n  --create-bucket-configuration LocationConstraint=ap-northeast-1<\/pre>\n<p><code>ap-northeast-1<\/code> \u306a\u3069 <code>us-east-1<\/code> \u4ee5\u5916\u306e\u30ea\u30fc\u30b8\u30e7\u30f3\u3067\u306f <code>--create-bucket-configuration LocationConstraint=...<\/code> \u304c\u5fc5\u9808\u3002<code>us-east-1<\/code> \u306e\u5834\u5408\u306f\u9006\u306b\u4ed8\u3051\u308b\u3068\u30a8\u30e9\u30fc\u306b\u306a\u308b\u3002<\/p>\n<h3>2. \u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u7528\u610f\u3057\u3066\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3059\u308b<\/h3>\n<pre class=\"lang:default decode:true\">mkdir -p site\ncat &gt; site\/index.html &lt;&lt;'HTML'\n&lt;!doctype html&gt;\n&lt;html lang=\"ja\"&gt;\n&lt;head&gt;&lt;meta charset=\"utf-8\"&gt;&lt;title&gt;Static on S3&lt;\/title&gt;&lt;\/head&gt;\n&lt;body&gt;&lt;h1&gt;Hello from S3&lt;\/h1&gt;&lt;\/body&gt;\n&lt;\/html&gt;\nHTML\n\ncat &gt; site\/error.html &lt;&lt;'HTML'\n&lt;!doctype html&gt;\n&lt;html lang=\"ja\"&gt;\n&lt;head&gt;&lt;meta charset=\"utf-8\"&gt;&lt;title&gt;Not Found&lt;\/title&gt;&lt;\/head&gt;\n&lt;body&gt;&lt;h1&gt;404 Not Found&lt;\/h1&gt;&lt;\/body&gt;\n&lt;\/html&gt;\nHTML\n\naws s3 sync .\/site s3:\/\/example-static-site-20260912<\/pre>\n<h3>3. \u9759\u7684\u30a6\u30a7\u30d6\u30b5\u30a4\u30c8\u30db\u30b9\u30c6\u30a3\u30f3\u30b0\u3092\u6709\u52b9\u5316\u3059\u308b<\/h3>\n<pre class=\"lang:default decode:true\">aws s3 website s3:\/\/example-static-site-20260912 \\\n  --index-document index.html \\\n  --error-document error.html<\/pre>\n<h3>4. \u30d1\u30d6\u30ea\u30c3\u30af\u30a2\u30af\u30bb\u30b9\u3092\u8a31\u53ef\u3059\u308b<\/h3>\n<p>\u65b0\u898f\u30d0\u30b1\u30c3\u30c8\u306f\u30c7\u30d5\u30a9\u30eb\u30c8\u3067\u5168\u516c\u958b\u304c\u30d6\u30ed\u30c3\u30af\u3055\u308c\u3066\u3044\u308b\u3002\u30d1\u30bf\u30fc\u30f31 \u3067\u306f\u76f4\u63a5\u30a2\u30af\u30bb\u30b9\u3092\u8a31\u53ef\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u305f\u3081\u3001\u30d6\u30ed\u30c3\u30af\u3092\u89e3\u9664\u3057\u3066\u304b\u3089\u30d0\u30b1\u30c3\u30c8\u30dd\u30ea\u30b7\u30fc\u3092\u4ed8\u4e0e\u3059\u308b\u3002<\/p>\n<pre class=\"lang:default decode:true\">aws s3api put-public-access-block \\\n  --bucket example-static-site-20260912 \\\n  --public-access-block-configuration \\\n  BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false<\/pre>\n<pre class=\"lang:default decode:true\">cat &gt; policy.json &lt;&lt;'JSON'\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"PublicReadGetObject\",\n      \"Effect\": \"Allow\",\n      \"Principal\": \"*\",\n      \"Action\": \"s3:GetObject\",\n      \"Resource\": \"arn:aws:s3:::example-static-site-20260912\/*\"\n    }\n  ]\n}\nJSON\n\naws s3api put-bucket-policy \\\n  --bucket example-static-site-20260912 \\\n  --policy file:\/\/policy.json<\/pre>\n<h3>5. \u30a2\u30af\u30bb\u30b9\u3057\u3066\u78ba\u8a8d\u3059\u308b<\/h3>\n<p>\u30a6\u30a7\u30d6\u30b5\u30a4\u30c8\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u306f\u6b21\u306e\u5f62\u5f0f\u306b\u306a\u308b\uff08\u30ea\u30fc\u30b8\u30e7\u30f3\u306b\u3088\u3063\u3066\u30c9\u30e1\u30a4\u30f3\u304c\u7570\u306a\u308b\uff09\u3002<\/p>\n<pre class=\"lang:default decode:true\">http:\/\/example-static-site-20260912.s3-website-ap-northeast-1.amazonaws.com\/<\/pre>\n<pre class=\"lang:default decode:true\">curl -I http:\/\/example-static-site-20260912.s3-website-ap-northeast-1.amazonaws.com\/\n# HTTP\/1.1 200 OK \u304c\u8fd4\u308c\u3070OK<\/pre>\n<h3>\u3053\u306e\u30d1\u30bf\u30fc\u30f3\u306e\u9650\u754c<\/h3>\n<ul>\n<li><strong>HTTPS \u975e\u5bfe\u5fdc<\/strong>\u3002\u30a6\u30a7\u30d6\u30b5\u30a4\u30c8\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u306f HTTP \u306e\u307f<\/li>\n<li><strong>\u30d0\u30b1\u30c3\u30c8\u3092\u516c\u958b\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b<\/strong>\u3002\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u89b3\u70b9\u3067\u306f\u907f\u3051\u305f\u3044<\/li>\n<li><strong>\u30a2\u30af\u30bb\u30b9\u30ed\u30b0\u30fb\u30ad\u30e3\u30c3\u30b7\u30e5\u30fb\u5730\u7406\u5236\u9650\u306a\u3069\u306e\u5236\u5fa1\u304c\u3067\u304d\u306a\u3044<\/strong><\/li>\n<\/ul>\n<p>\u5b66\u7fd2\u7528\u9014\u3068\u3057\u3066\u306f\u5341\u5206\u3060\u304c\u3001\u672c\u756a\u3067\u306f\u6b21\u306e\u30d1\u30bf\u30fc\u30f32 \u306b\u9032\u3080\u3002<\/p>\n<h2>\u30d1\u30bf\u30fc\u30f32: CloudFront + OAC\uff08\u30d0\u30b1\u30c3\u30c8\u975e\u516c\u958b\u306e\u307e\u307e HTTPS \u914d\u4fe1\uff09<\/h2>\n<h3>\u69cb\u6210\u306e\u8003\u3048\u65b9<\/h3>\n<ul>\n<li>S3 \u30d0\u30b1\u30c3\u30c8\u306f<strong>\u975e\u516c\u958b\u306e\u307e\u307e<\/strong>\u306b\u3059\u308b\uff08\u30d1\u30d6\u30ea\u30c3\u30af\u30a2\u30af\u30bb\u30b9\u30d6\u30ed\u30c3\u30af\u306f\u5168\u90e8 ON \u306e\u307e\u307e\uff09<\/li>\n<li>CloudFront \u30c7\u30a3\u30b9\u30c8\u30ea\u30d3\u30e5\u30fc\u30b7\u30e7\u30f3\u3092\u524d\u6bb5\u306b\u7f6e\u304d\u3001<strong>OAC<\/strong> \u3067 CloudFront \u304b\u3089\u306e\u307f S3 \u3092\u8aad\u3081\u308b\u3088\u3046\u306b\u3059\u308b<\/li>\n<li>HTTPS \u306f CloudFront \u306e\u30c7\u30d5\u30a9\u30eb\u30c8\u8a3c\u660e\u66f8\u3001\u72ec\u81ea\u30c9\u30e1\u30a4\u30f3\u306a\u3089 ACM \u8a3c\u660e\u66f8\u3092\u4f7f\u3046<\/li>\n<\/ul>\n<p>\u304b\u3064\u3066\u306f OAI\uff08Origin Access Identity\uff09\u304c\u4f7f\u308f\u308c\u3066\u3044\u305f\u304c\u3001\u73fe\u5728\u306f <strong>OAC \u304c\u63a8\u5968<\/strong>\u3002SSE-KMS \u6697\u53f7\u5316\u30d0\u30b1\u30c3\u30c8\u3084\u65b0\u3057\u3044\u30ea\u30fc\u30b8\u30e7\u30f3\u306b\u3082\u5bfe\u5fdc\u3059\u308b\u3002\u65b0\u898f\u69cb\u7bc9\u3067\u306f OAC \u3092\u9078\u3076\u3002<\/p>\n<h3>1. \u30d0\u30b1\u30c3\u30c8\u306f\u975e\u516c\u958b\u306e\u307e\u307e\u4f5c\u308b<\/h3>\n<p>\u30d1\u30bf\u30fc\u30f31 \u306e\u624b\u98064\uff08\u30d1\u30d6\u30ea\u30c3\u30af\u30a2\u30af\u30bb\u30b9\u8a31\u53ef\u3068\u30d0\u30b1\u30c3\u30c8\u30dd\u30ea\u30b7\u30fc\uff09\u306f<strong>\u5b9f\u65bd\u3057\u306a\u3044<\/strong>\u3002\u30d1\u30d6\u30ea\u30c3\u30af\u30a2\u30af\u30bb\u30b9\u30d6\u30ed\u30c3\u30af\u306f ON \u306e\u307e\u307e\u306b\u3057\u3066\u304a\u304f\u3002\u30aa\u30ea\u30b8\u30f3\u3068\u3057\u3066\u4f7f\u3046\u305f\u3081\u3001\u9759\u7684\u30a6\u30a7\u30d6\u30b5\u30a4\u30c8\u30db\u30b9\u30c6\u30a3\u30f3\u30b0\uff08\u624b\u98063\uff09\u3082\u4e0d\u8981\u3067\u3001\u901a\u5e38\u306e S3 \u30d0\u30b1\u30c3\u30c8\u3068\u3057\u3066\u6271\u3046\u3002<\/p>\n<h3>2. OAC \u3092\u4f5c\u6210\u3059\u308b<\/h3>\n<pre class=\"lang:default decode:true\">aws cloudfront create-origin-access-control \\\n  --origin-access-control-config \\\n  Name=example-static-site-oac,SigningProtocol=sigv4,SigningBehavior=always,OriginAccessControlOriginType=s3<\/pre>\n<p>\u8fd4\u3063\u3066\u304f\u308b <code>Id<\/code>\uff08OAC \u306e ID\uff09\u3092\u63a7\u3048\u3066\u304a\u304f\u3002<\/p>\n<h3>3. CloudFront \u30c7\u30a3\u30b9\u30c8\u30ea\u30d3\u30e5\u30fc\u30b7\u30e7\u30f3\u3092\u4f5c\u6210\u3059\u308b<\/h3>\n<p>\u30de\u30cd\u30b8\u30e1\u30f3\u30c8\u30b3\u30f3\u30bd\u30fc\u30eb\u3067\u4f5c\u308b\u5834\u5408\u306f\u6b21\u3092\u6307\u5b9a\u3059\u308b\u3002<\/p>\n<ul>\n<li><strong>\u30aa\u30ea\u30b8\u30f3\u30c9\u30e1\u30a4\u30f3<\/strong>: <code>example-static-site-20260912.s3.ap-northeast-1.amazonaws.com<\/code>\uff08\u30a6\u30a7\u30d6\u30b5\u30a4\u30c8\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u3067\u306f\u306a\u304f <strong>REST API \u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8<\/strong>\u3092\u9078\u3076\uff09<\/li>\n<li><strong>\u30aa\u30ea\u30b8\u30f3\u30a2\u30af\u30bb\u30b9<\/strong>: Origin access control settings \u3092\u9078\u3073\u3001\u624b\u98062 \u306e OAC \u3092\u6307\u5b9a<\/li>\n<li><strong>\u30d3\u30e5\u30fc\u30a2\u30d7\u30ed\u30c8\u30b3\u30eb\u30dd\u30ea\u30b7\u30fc<\/strong>: Redirect HTTP to HTTPS<\/li>\n<li><strong>\u30c7\u30d5\u30a9\u30eb\u30c8\u30eb\u30fc\u30c8\u30aa\u30d6\u30b8\u30a7\u30af\u30c8<\/strong>: <code>index.html<\/code><\/li>\n<\/ul>\n<p>CLI \u3067\u4f5c\u308b\u5834\u5408\u306f <code>distribution-config.json<\/code> \u3092\u7d44\u307f\u7acb\u3066\u3066 <code>aws cloudfront create-distribution --distribution-config file:\/\/distribution-config.json<\/code> \u3092\u5b9f\u884c\u3059\u308b\u3002\u9805\u76ee\u304c\u591a\u3044\u305f\u3081\u3001\u521d\u56de\u306f\u30b3\u30f3\u30bd\u30fc\u30eb\u3067\u4f5c\u3063\u3066\u8a2d\u5b9a\u3092\u628a\u63e1\u3059\u308b\u306e\u304c\u304a\u3059\u3059\u3081\u3002<\/p>\n<h3>4. \u30d0\u30b1\u30c3\u30c8\u30dd\u30ea\u30b7\u30fc\u3067 CloudFront \u304b\u3089\u306e\u30a2\u30af\u30bb\u30b9\u3060\u3051\u8a31\u53ef\u3059\u308b<\/h3>\n<p>CloudFront \u30c7\u30a3\u30b9\u30c8\u30ea\u30d3\u30e5\u30fc\u30b7\u30e7\u30f3\u3092\u4f5c\u308b\u3068\u3001\u30b3\u30f3\u30bd\u30fc\u30eb\u306b\u300cS3 \u30d0\u30b1\u30c3\u30c8\u306b\u8cbc\u308b\u3079\u304d\u30dd\u30ea\u30b7\u30fc\u300d\u304c\u8868\u793a\u3055\u308c\u308b\u3002\u5185\u5bb9\u306f\u6b21\u306e\u5f62\u306b\u306a\u308b\u3002<\/p>\n<pre class=\"lang:default decode:true\">{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"AllowCloudFrontServicePrincipal\",\n      \"Effect\": \"Allow\",\n      \"Principal\": { \"Service\": \"cloudfront.amazonaws.com\" },\n      \"Action\": \"s3:GetObject\",\n      \"Resource\": \"arn:aws:s3:::example-static-site-20260912\/*\",\n      \"Condition\": {\n        \"StringEquals\": {\n          \"AWS:SourceArn\": \"arn:aws:cloudfront::&lt;ACCOUNT_ID&gt;:distribution\/&lt;DISTRIBUTION_ID&gt;\"\n        }\n      }\n    }\n  ]\n}<\/pre>\n<p>\u3053\u306e\u30dd\u30ea\u30b7\u30fc\u306b\u3088\u308a\u300c\u7279\u5b9a\u306e CloudFront \u30c7\u30a3\u30b9\u30c8\u30ea\u30d3\u30e5\u30fc\u30b7\u30e7\u30f3\u7d4c\u7531\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u3060\u3051\u300d\u304c <code>GetObject<\/code> \u3092\u8a31\u53ef\u3055\u308c\u308b\u3002\u30d0\u30b1\u30c3\u30c8\u81ea\u4f53\u306f\u975e\u516c\u958b\u306e\u307e\u307e\u3060\u3002<\/p>\n<h3>5. \u72ec\u81ea\u30c9\u30e1\u30a4\u30f3\u3068 HTTPS\uff08\u4efb\u610f\uff09<\/h3>\n<ol>\n<li><strong>ACM \u3067\u8a3c\u660e\u66f8\u3092\u767a\u884c<\/strong>\u3059\u308b\u3002CloudFront \u3067\u4f7f\u3046\u8a3c\u660e\u66f8\u306f <strong><code>us-east-1<\/code>\uff08\u30d0\u30fc\u30b8\u30cb\u30a2\u5317\u90e8\uff09\u3067\u767a\u884c<\/strong>\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\uff08\u6771\u4eac\u30ea\u30fc\u30b8\u30e7\u30f3\u3067\u306f\u306a\u3044\uff09<\/li>\n<li>CloudFront \u30c7\u30a3\u30b9\u30c8\u30ea\u30d3\u30e5\u30fc\u30b7\u30e7\u30f3\u306e <strong>Alternate domain name (CNAME)<\/strong> \u306b\u72ec\u81ea\u30c9\u30e1\u30a4\u30f3\u3092\u8ffd\u52a0\u3057\u3001\u8a3c\u660e\u66f8\u3092\u7d10\u4ed8\u3051\u308b<\/li>\n<li>Route 53 \u3067 <strong>A \u30ec\u30b3\u30fc\u30c9\uff08Alias\uff09<\/strong>\u3092 CloudFront \u30c7\u30a3\u30b9\u30c8\u30ea\u30d3\u30e5\u30fc\u30b7\u30e7\u30f3\u306b\u5411\u3051\u308b<\/li>\n<\/ol>\n<pre class=\"lang:default decode:true\">aws acm request-certificate \\\n  --domain-name www.example.com \\\n  --validation-method DNS \\\n  --region us-east-1<\/pre>\n<h2>\u5b9f\u88c5\u4f8b: \u30c7\u30d7\u30ed\u30a4\u3068\u66f4\u65b0\u306e\u81ea\u52d5\u5316<\/h2>\n<pre class=\"lang:default decode:true\"># 1. \u30d3\u30eb\u30c9\u6210\u679c\u7269\u3092\u540c\u671f\uff08\u4e0d\u8981\u30d5\u30a1\u30a4\u30eb\u306f\u524a\u9664\u3001\u30ad\u30e3\u30c3\u30b7\u30e5\u5236\u5fa1\u30d8\u30c3\u30c0\u3092\u4ed8\u4e0e\uff09\naws s3 sync .\/dist s3:\/\/example-static-site-20260912 \\\n  --delete \\\n  --cache-control \"public, max-age=31536000, immutable\" \\\n  --exclude \"index.html\"\n\n# 2. index.html \u306f\u77ed\u3081\u306e\u30ad\u30e3\u30c3\u30b7\u30e5\u306b\u3059\u308b\uff08\u5185\u5bb9\u304c\u5909\u308f\u308b\u305f\u3081\uff09\naws s3 cp .\/dist\/index.html s3:\/\/example-static-site-20260912\/index.html \\\n  --cache-control \"public, max-age=60\"\n\n# 3. CloudFront \u306e\u30ad\u30e3\u30c3\u30b7\u30e5\u3092\u7121\u52b9\u5316\naws cloudfront create-invalidation \\\n  --distribution-id &lt;DISTRIBUTION_ID&gt; \\\n  --paths \"\/*\"<\/pre>\n<p>\u30cf\u30c3\u30b7\u30e5\u4ed8\u304d\u306e\u30a2\u30bb\u30c3\u30c8\uff08<code>app.abc123.js<\/code> \u306a\u3069\uff09\u306f\u9577\u671f\u30ad\u30e3\u30c3\u30b7\u30e5\u3001<code>index.html<\/code> \u306f\u77ed\u671f\u30ad\u30e3\u30c3\u30b7\u30e5\u306b\u3059\u308b\u306e\u304c\u30bb\u30aa\u30ea\u30fc\u3002\u7121\u52b9\u5316\u30ea\u30af\u30a8\u30b9\u30c8\u306f\u7121\u6599\u67a0\u3092\u8d85\u3048\u308b\u3068\u8ab2\u91d1\u5bfe\u8c61\u306a\u306e\u3067 <code>\/*<\/code> \u306e\u4e71\u767a\u306b\u306f\u6ce8\u610f\u3059\u308b\u3002<\/p>\n<h2>\u78ba\u8a8d\u65b9\u6cd5<\/h2>\n<ul>\n<li><strong>\u30d1\u30bf\u30fc\u30f31<\/strong>: \u30a6\u30a7\u30d6\u30b5\u30a4\u30c8\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u306b <code>curl -I<\/code> \u3057\u3066 <code>200 OK<\/code> \u3092\u78ba\u8a8d\u3002\u5b58\u5728\u3057\u306a\u3044\u30d1\u30b9\u3067 <code>error.html<\/code> \u304c\u8fd4\u308b\u304b\u3082\u78ba\u8a8d\u3059\u308b<\/li>\n<li><strong>\u30d1\u30bf\u30fc\u30f32<\/strong>: CloudFront \u30c9\u30e1\u30a4\u30f3\uff08<code>dxxxxxxxxxxxxx.cloudfront.net<\/code>\uff09\u307e\u305f\u306f\u72ec\u81ea\u30c9\u30e1\u30a4\u30f3\u306b HTTPS \u3067\u30a2\u30af\u30bb\u30b9\u3057\u3001<code>200<\/code> \u304c\u8fd4\u308b\u3053\u3068\u3001S3 \u306e REST \u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u306b\u76f4\u30a2\u30af\u30bb\u30b9\u3059\u308b\u3068 <code>AccessDenied<\/code> \u306b\u306a\u308b\u3053\u3068\uff08\uff1d\u30d0\u30b1\u30c3\u30c8\u304c\u975e\u516c\u958b\uff09\u3092\u78ba\u8a8d\u3059\u308b<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true\"># \u975e\u516c\u958b\u304c\u52b9\u3044\u3066\u3044\u308b\u304b\u306e\u78ba\u8a8d\uff08AccessDenied \u304c\u8fd4\u308c\u3070\u6b63\u3057\u3044\uff09\ncurl -I https:\/\/example-static-site-20260912.s3.ap-northeast-1.amazonaws.com\/index.html<\/pre>\n<h2>\u6ce8\u610f\u70b9<\/h2>\n<ul>\n<li><strong>\u30d0\u30b1\u30c3\u30c8\u540d\u306f\u4e16\u754c\u3067\u4e00\u610f<\/strong>\u3002\u30d7\u30ec\u30d5\u30a3\u30c3\u30af\u30b9\uff0b\u65e5\u4ed8\u306a\u3069\u3067\u4e00\u610f\u6027\u3092\u78ba\u4fdd\u3059\u308b<\/li>\n<li><strong>CloudFront \u7528\u306e ACM \u8a3c\u660e\u66f8\u306f <code>us-east-1<\/code> \u306e\u307f<\/strong>\u3002\u3053\u3053\u3067\u8a70\u307e\u308b\u4eba\u304c\u591a\u3044<\/li>\n<li><strong>SPA \u306e\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0<\/strong>\u3092\u4f7f\u3046\u5834\u5408\u3001\u5b58\u5728\u3057\u306a\u3044\u30d1\u30b9\u3067 403\/404 \u306b\u306a\u308b\u3002CloudFront \u306e\u300c\u30ab\u30b9\u30bf\u30e0\u30a8\u30e9\u30fc\u30ec\u30b9\u30dd\u30f3\u30b9\u300d\u3067 403\/404 \u3092 <code>\/index.html<\/code>\u30fb\u30b9\u30c6\u30fc\u30bf\u30b9 200 \u306b\u66f8\u304d\u63db\u3048\u308b<\/li>\n<li><strong>\u30d1\u30d6\u30ea\u30c3\u30af\u30a2\u30af\u30bb\u30b9\u30d6\u30ed\u30c3\u30af\u306e\u6271\u3044<\/strong>\u3002\u30d1\u30bf\u30fc\u30f32 \u3067\u306f\u7d76\u5bfe\u306b\u89e3\u9664\u3057\u306a\u3044\u3002\u89e3\u9664\u3059\u308b\u3068 OAC \u3067\u5b88\u3063\u3066\u3044\u308b\u610f\u5473\u304c\u306a\u304f\u306a\u308b<\/li>\n<li><strong>\u30ad\u30e3\u30c3\u30b7\u30e5\u7121\u52b9\u5316\u306e\u30b3\u30b9\u30c8<\/strong>\u3002\u30c7\u30d7\u30ed\u30a4\u306e\u305f\u3073\u306b <code>\/*<\/code> \u3092\u7121\u52b9\u5316\u3059\u308b\u3068\u7121\u6599\u67a0\u3092\u8d85\u3048\u308b\u53ef\u80fd\u6027\u304c\u3042\u308b\u3002\u30d1\u30b9\u3092\u7d5e\u308b\u304b\u3001\u30d5\u30a1\u30a4\u30eb\u540d\u306b\u30cf\u30c3\u30b7\u30e5\u3092\u542b\u3081\u3066\u7121\u52b9\u5316\u81ea\u4f53\u3092\u6e1b\u3089\u3059<\/li>\n<\/ul>\n<h2>\u307e\u3068\u3081<\/h2>\n<ul>\n<li>\u9759\u7684\u30b5\u30a4\u30c8\u306e\u30db\u30b9\u30c6\u30a3\u30f3\u30b0\u306f\u3001\u307e\u305a S3 \u306e\u9759\u7684\u30a6\u30a7\u30d6\u30b5\u30a4\u30c8\u30db\u30b9\u30c6\u30a3\u30f3\u30b0\u3067\u4ed5\u7d44\u307f\u3092\u7406\u89e3\u3067\u304d\u308b<\/li>\n<li>HTTPS\u30fb\u72ec\u81ea\u30c9\u30e1\u30a4\u30f3\u30fb\u30d0\u30b1\u30c3\u30c8\u975e\u516c\u958b\u3092\u6e80\u305f\u3059\u306a\u3089 <strong>CloudFront + OAC<\/strong> \u304c\u672c\u756a\u306e\u5b9a\u756a\u69cb\u6210<\/li>\n<li>ACM \u8a3c\u660e\u66f8\u306f <code>us-east-1<\/code>\u3001SPA \u306f\u30ab\u30b9\u30bf\u30e0\u30a8\u30e9\u30fc\u30ec\u30b9\u30dd\u30f3\u30b9\u3001\u30ad\u30e3\u30c3\u30b7\u30e5\u7121\u52b9\u5316\u306e\u30b3\u30b9\u30c8\u3001\u3053\u306e 3 \u70b9\u304c\u4e3b\u306a\u30cf\u30de\u308a\u3069\u3053\u308d<\/li>\n<li>\u30c7\u30d7\u30ed\u30a4\u306f <code>aws s3 sync --delete<\/code> \uff0b\u30ad\u30e3\u30c3\u30b7\u30e5\u5236\u5fa1\u30d8\u30c3\u30c0 \uff0b CloudFront invalidation \u3092\u30bb\u30c3\u30c8\u3067\u81ea\u52d5\u5316\u3059\u308b<\/li>\n<\/ul>\n<p>\u30b5\u30fc\u30d0\u30fc\u30ec\u30b9\u3067\u4f4e\u30b3\u30b9\u30c8\u3001\u30b9\u30b1\u30fc\u30eb\u3092\u6c17\u306b\u305b\u305a\u914d\u4fe1\u3067\u304d\u308b\u306e\u304c S3 \u30db\u30b9\u30c6\u30a3\u30f3\u30b0\u306e\u5f37\u307f\u3002\u6700\u5c0f\u69cb\u6210\u304b\u3089\u59cb\u3081\u3066\u3001\u8981\u4ef6\u306b\u5fdc\u3058\u3066 CloudFront \u3092\u524d\u6bb5\u306b\u8db3\u3057\u3066\u3044\u304f\u306e\u304c\u5b9f\u52d9\u7684\u306a\u9032\u3081\u65b9\u3060\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>HTML\/CSS\/JS \u3060\u3051\u3067\u5b8c\u7d50\u3059\u308b\u9759\u7684\u30b5\u30a4\u30c8\uff08\u30e9\u30f3\u30c7\u30a3\u30f3\u30b0\u30da\u30fc\u30b8\u3001\u88fd\u54c1\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3001SPA \u306e\u30d3\u30eb\u30c9\u6210\u679c\u7269\u306a\u3069\uff09\u306f\u3001\u30b5\u30fc\u30d0\u30fc\u3092\u7acb\u3066\u305a\u306b Amazon S3 \u3067\u30db\u30b9\u30c6\u30a3\u30f3\u30b0\u3067\u304d\u308b\u3002\u672c\u8a18\u4e8b\u3067\u306f\u6b21\u306e 2 \u30d1\u30bf\u30fc\u30f3\u3092\u30cf\u30f3\u30ba\u30aa\u30f3\u5f62\u5f0f\u3067\u69cb\u7bc9\u3059\u308b\u3002<\/p>\n","protected":false},"author":1,"featured_media":3532,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"sns_share_botton_hide":"","vkExUnit_sns_title":"","_vk_print_noindex":"","sitemap_hide":"","_veu_custom_css":"","veu_display_promotion_alert":"","vkexunit_cta_each_option":"","_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[75],"tags":[499,1199,967,495,68],"class_list":["post-3533","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-code-of-serverside","tag-aws","tag-s3","tag-spa","tag-495","tag-68"],"veu_head_title_object":{"title":"","add_site_title":""},"jetpack_publicize_connections":[],"jetpack-related-posts":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/qol-kk.com\/wp2\/wp-content\/uploads\/2026\/10\/20260912-00mtxn7z-thumbnail.jpg","_links":{"self":[{"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/posts\/3533","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/comments?post=3533"}],"version-history":[{"count":1,"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/posts\/3533\/revisions"}],"predecessor-version":[{"id":3534,"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/posts\/3533\/revisions\/3534"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/media\/3532"}],"wp:attachment":[{"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/media?parent=3533"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/categories?post=3533"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qol-kk.com\/wp2\/wp-json\/wp\/v2\/tags?post=3533"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}