0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

S3 + CloudFrontの静的配信サイトでApacheの.htaccessに対応する

0
Last updated at Posted at 2026-07-12

S3 + CloudFrontで.htaccessを使えるようにした

S3 + CloudFrontで静的サイトを配信する場合、リダイレクトやBasic認証はCloudFront Functionsに書くことが多いと思います。

技術的にはそれで困りません。ただ、VPSやレンタルサーバーから移行すると運用が変わります。

以前はデザイナーがHTMLと一緒に.htaccessをアップロードしていたのに、移行後はリダイレクトを1件追加するだけでもエンジニアがCloudFront Functionsを修正することになります。

そこを変えたくなかったので、S3へアップロードした.htaccessをCloudFront Functionsの設定として使う仕組みを作りました。

n-iskw/s3-cloudfront-htaccess-bridge

Apache互換サーバーを作るものではありません。リダイレクト、Basic認証、DirectoryIndexなど、静的サイトの運用で使いそうな範囲だけに対応しています。

コンテンツ側の操作

導入後の操作は、S3へコンテンツと.htaccessをアップロードするだけです。AWS ConsoleでもCyberduckでも構いません。

リダイレクトは普通の.htaccessと同じように書けます。

Redirect 301 /old/ /new/
Redirect 302 /campaign-old/ /campaign/

Basic認証は次のように設定します。

AuthType Basic
AuthName "Maintenance"
AuthUserFile .htpasswd
Require valid-user

同じディレクトリへ.htpasswdもアップロードします。現在対応しているのは{SHA}形式です。

htpasswd -cs .htpasswd preview

確認用のIPアドレスを認証対象から外すこともできます。

Require ip 203.0.113.10 198.51.100.0/24

下位ディレクトリに.htaccessを置いた場合は、そのディレクトリ以下に適用します。ルートの設定は下位へ継承します。

コンテンツを管理する人はCloudFront FunctionsやKeyValueStoreを触りません。ここがこの仕組みの目的です。

構成

.htaccessをリクエストのたびにS3から読むことはできないため、更新時にCloudFront KeyValueStoreへ変換しておきます。

S3へ.htaccessまたは.htpasswdをアップロード
  ↓ S3イベント
Lambdaで全設定を読み直して検証
  ↓
CloudFront KeyValueStoreへ保存
  ↓ viewer-request
CloudFront Functionsで適用

S3上のファイルが正本です。Lambdaは.htaccessを解析し、CloudFront Functionsから扱いやすい形へ変換してKeyValueStoreへ保存します。

CloudFront Functionsでは次の順に処理します。

  1. .htaccess.htpasswdなど、公開してはいけないパスを拒否
  2. Basic認証
  3. リダイレクト
  4. DirectoryIndexの解決

設定を間違えた場合

未対応のディレクティブやリダイレクトループが含まれていた場合は反映しません。それまで使われていた設定を維持します。

結果はS3へ保存します。

_control-history/published/
_control-history/rejected/

.htaccess.htpasswd_control-history/へのHTTPアクセスはCloudFront Functions側で403にしています。

自由に書ける.htaccessをそのまま実行するのではなく、対応している記述だけを検証して反映する作りです。

対応していないもの

Apacheの.htaccessを完全に再現しているわけではありません。現在の主な非対応項目は次のとおりです。

  • RewriteCond
  • SPAフォールバック
  • Digest認証
  • IPv6のアクセスルール
  • bcrypt、Apache MD5、crypt形式の.htpasswd

DirectoryIndexにも制限があります。

DirectoryIndex index.html index.htm

このように複数書いても、常に先頭のindex.htmlを使います。CloudFront FunctionsからS3上のファイルの有無を確認しないため、index.htmlがなければindex.htmには進まず404になります。

未対応の記述を適当に読み替えると、書いた人が想定していない動作になります。そのため、解釈できない設定は反映しない方針にしています。

既存サイトへの導入

既存のS3バケットとCloudFront Distributionへ追加するためのCloudFormationテンプレートを入れています。

テンプレートが作るのはCloudFront KeyValueStore、Lambda、IAMロール、CloudWatch Logs、CloudFront Functionsです。既存バケットの通知設定とCloudFront Distributionは変更しません。

この2か所は既存設定との衝突があり得るため、現在の設定を確認してからCLIまたは既存のIaCで接続します。

特にviewer-requestのCloudFront Functionsは、同じCache Behaviorへ複数登録できません。すでに関数を使っている場合は、既存の処理と統合する必要があります。

導入手順はIntegration Guideに書きました。

まとめ

CloudFront Functionsを直接管理した方がいいサイトもあります。リダイレクトをIaCで厳密に管理したい場合は、その方が素直です。

この仕組みは、これまで.htaccessをコンテンツと一緒に管理してきた現場向けです。配信基盤をS3 + CloudFrontへ変えても、簡単な変更までエンジニアの作業に戻さないために作りました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?