AWS
S3
route53
CloudFront
Terraform

初めてaws・terraform触ってみてどぶ沼に落ちた。

静的ページをs3 + cloudfrontで構築した時つまづいたことを汚い箇条書きでまとめます。

エンジニアもどき+論理的思考がないので読みにくい記事かと思います。


背景

もともと、ec2で静的ページ見ていたところをs3 < - cloudfrontで見られるようにするタスクいただいて、多々つまづきました。

awsのリファレンスを見るべきだったり、terraformのリファレンス見るべきだったり、どちらにも乗ってなかったり、まとまってる方が助かったので、qiitaに載せます。


対象


  1. AWS初心者

  2. terraform初心者

  3. s3 + cloudfrontでサービス公開する人

基本的に公式リファレンスor terraformのgitに書いてあることしか書いていないです。(+しょうもない経験談)


学び


  • terraformで作ったらawsコンソールからいじっちゃいけない。


    • そのあとにterraformから修正しようとするとコンフリクト起こして何もできなくなることがある。



  • ディレクトリ構成を大幅に変更するとterraformが動かなくなる。


    • terraform.tfstateを頑張っていじればなんとかなったりする。


      • terraform.tfstate.backupはいじらなくても良い





  • lambda@edge使う


    • ソースはローカルでzipファイルを作成しておくか、あらかじめS3にアップしておく必要がある



  • lambda@edgeが削除できない


    • cloudfrontが紐づいていると削除できない。



  • s3のbucket policyでIP制限したい。


    • cloudfrontからs3が見られなくなる。


      • cloudfront通す場合はs3でip制限しちゃダメ。ip制限するならwafでやる





  • webhostingしていないs3のhostをcloudfrontに設定する


    • webhostingしていない場合は、${bucket_name}.s3.amazonaws.com が紐づけるhostになる。



  • cloudfront + s3 はindex documentが404


    • ドメイン直下のルートパスはcloudfrontから設定できるが、サブディレクトリはcloudfrontからは設定できない。

    • subdirectoryのindex documentの設定はs3でwebhostingするのがスタンダード?


      • webhostingするとs3が直で見えてしまうので、googleのインデックスに引っかかる可能性がある。見えてもいいのか注意が必要。



    • terraformからcloudfrontにwebhostingされたs3のhostを設定すると、cloudfrontのorigin typeがうまく機能しなくてerrorになるっぽい



      • custom_origin_configを設定すると、cloudfrontのorigin typeの解決ができる?とりあえず、うまく行く。


        • terraformのgit-issueになってるっぽい。








  • terraform destroy でcloudfrontが削除できない。


    • cloudfrontを削除する前にdisableにしなければいけない。


      • delete自体は早いが、disableには3時間くらいかかるので要注意





  • エラーページはルートパスにリダイレクトする


    • cloudfrontで custom_error_response を設定する。


      • 3xx系ではリダイレクトができないのがawsの仕様。





  • route53でnakedなドメインにcloudfrontを適用


    • cnameだけは登録できない。

    • 各ドメインにはAレコードの登録が必要なので、cnameではなく、aレコードで登録する。


      • aliasという概念でドメインをaレコードにいい感じで登録できる。(正直、あまりよくわかってない。)

      • aliasで指定する場合はttlをセットできない。





  • importしたssl証明書をcloudfrontに紐づける(awsが発行してないもの)



    • aws_acm_certificate.acm.types = IMPORTED を使う