LoginSignup
0
0

More than 1 year has passed since last update.

Astro × AWS(s3,CloudFront)でドキュメントルート以外に遷移した際、AccessDeniedになりハマった件

Posted at

はじめに

タイトルの件で少し詰まったので、同じ問題で困っている方への一助となれば幸いです。

状況

最近流行り?のSSGであるAstro(今回利用したテンプレートはastro-paper)をs3にデプロイした際に、s3で指定したドキュメントルート(index.html)ではページが表示できているのですが、他のページに移動した際にAccessDeniedとなり、期待する動作ができませんでした。

原因

遷移した先のパスが違いました。

そのため別途設定が必要でした。

Astroではbuildした際に/dist配下に静的ページ表示用のhtmlファイルが出力されるのですが、そちらのディレクトリ構成を把握できていませんでした。
/dist以下のディレクトリ構成は以下のようになります。

├── index.html
└── posts
    ├── 1
    │   └── index.html
    ├── hazimemashite
    │   └── index.html
    └── index.html

※対象の部分を抜粋

今回意図する動作として最上位の階層のindex.htmlからhazimemashiteディレクトリ内のindex.htmlのページへと遷移したいといった感じです。

実際に遷移した際のパスは
任意のドメイン名(またはCloudFrontのドメイン)/posts/hazimemashite/
となっており、hazimemashiteディレクトリ内のindex.htmlを参照できていませんでした。

実際に
任意のドメイン名(またはCloudFrontのドメイン)/posts/hazimemashite/index.html
とすると期待するページを表示できました。

しかし遷移するたびに手動でindex.htmlを付け足すのはユーザビリティが最悪なので(笑)、、、

Astroのドキュメントに以下の方法がありました。

解決方法

CloudFront Functionsの実装でした。

astrofunction.js
function handler(event) {
  var request = event.request;
  var uri = request.uri;

  // Check whether the URI is missing a file name.
  if (uri.endsWith('/')) {
    request.uri += 'index.html';
  } 
  // Check whether the URI is missing a file extension.
  else if (!uri.includes('.')) {
    request.uri += '/index.html';
  }

  return request;
}

 ドキュメントより引用

コードに関しては説明するまでもないですが、ユーザより/または.でパスのリクエストがあった際に参照するファイルは/または.以降のindex.htmlのファイルにするよとういうものです。

私はTerraFormでAWSリソースを管理していたため以下のように実装を進めました。

cloudfront.tf
# CloudFront Functionsリソースを定義
resource "aws_cloudfront_function" "astrofunction" {
  name    = "redirect"
  runtime = "cloudfront-js-1.0"
  comment = "redirect function"
  publish = true
  # 今回astrofunction.jsは./src内に配置しました
  code    = file("./src/astrofunction.js")
}

resource "aws_cloudfront_distribution" "cozycozy-blog" {
    
  default_cache_behavior {
    # default_cache_behavior内に関数を付与するコード追加
    function_association {
      event_type   = "viewer-request"
      function_arn = aws_cloudfront_function.astrofunction.arn
    }
  }
    
}

以上のコードを記述後terraform applyを問題なくリソースを更新後、
任意のドメイン名(またはCloudFrontのドメイン)/posts/hazimemashite/
のパスで無事、サブディレクトリのページに遷移できました!

終わりに

Astroのドキュメントは各プラットフォームごとにデプロイ方法が丁寧に描かれており、初心者に優しいなと感じました。

また今回実際に作成したページがこちらになります!
(スタイルとかレスポンシブがイマイチな気がするので勉強して直したい、、、)

読んでいただいた方ありがとうございました!

参考

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