背景
社Webを今まではレンタルサーバでHostしていたのですが、フォーム以外は極めてStaticな内容なので今流行りのサーバーレスな環境に移行してナレッジを貯め込みながらもコスト削減したいというところです。なお、すでに過去の偉人たちが残してくださっているドキュメントが多数ございますので、本記事では具体的にハマりそうなポイントを中心に書いていきたいと思います。
Before
自分が契約しているさくらインターネットさんに置いていました。フォーム部はphpで社内のSlackに飛ばすというものになっておりました。
After
大枠で下記な感じで対応しました。1
- Hostはs3
- SSL証明書はAmazon Certificate Manager && cloudfront
- フォームはStacktodoで相変わらずSlackに飛ばす
- Route53からCNAMEをcloudfrontに向ける
s3で静的コンテンツをHostする
もう説明は不要だと思います。この辺りなどを…
独自ドメインを使ってAmazon S3で静的Webサイトをホストする - Qiita
Amazon Certificate Manager via cloudfrontでSSL設定
SSLを設定する場合はどうしてもcloudfrontが必要になります。Amazon Certificate Managerを利用してSSL証明書を発行する必要があるのですが、cloudfrontで発行する証明書はUSなRegionで発行されている必要があるためcloudfrontのCreate Distributionから発行手続きを行ってください。ということでここが小さなハマりポイントになります。
Amazon Certificate Managerからドメイン確認のメールが飛んできますのでURLを踏んでAcceptしましょう。詳しい手順は以下を読むと良いでしょう。
S3+CloudFront+ACM(AWS Certificate Manager)でHTTPS静的サイトを作ってみた - Qiita
ビルドにしばらくかかりますのでChromeの恐竜と戯れるなどして待ちましょう(謎)
https://youtu.be/UtcGgJxVkfU
Stacktodoでフォームを作る
以前はSlackのIncoming Webhookを使ってphpでSlackに投稿していました。Lambda + API Gatewayを使うという方法もありますが、今回はこういったサービスを使ってみることにしました。(たぶん、飽きたらLambda + API Gatewayに移行するかもですが…)
Stacktodo | Superbot for Slack
一応、日本語でおk
という人のために説明しておきますと、Stacktodoとは…という説明は今回割愛しますが、物凄くお手軽にSlack BotをIntegrateしてくれるサービスみたいです。そのいくつかある機能の中のフォームを今回使いました。
https://stacktodo.com/tools/form
StacktodoでBotをセットアップする
英語ですがわかりやすいチュートリアルがあります。是非ご覧ください。
https://stacktodo.com/bot
Stacktodo BotをSlackに招待する
Slack ChannelにStacktodoを招待する
Slack Channelを作成 or 既存のSlack ChannelにStacktodoを招待して@stacktodo form here
で新しいフォームが作成されます。
https://youtu.be/xFFI8ZAw5f4
フォームタイトルやフィールド定義などをしたら@stacktodo form code
とするとEmbedするHTMLが出力されます。
https://youtu.be/iRrCgoOahtI
フォームの設定方法などのドキュメントは下記をご確認ください。
How to use the Form tool | Slack
@stacktodo form code
で出力したコードをHTMLにマージする
既存HTMLに自分が用意したCSSなどであたっている要素名(Classやidなど)といい感じにマージしてください。下記の例ですとformのidがs2do-form
となっているので合わせたりしました。簡単なValidationなどもついでにやっておくとなお良いでしょう。
<form id="s2do-form" action="#" method="POST">
<div class="form-group">
<label>name</label>
<input type="text" name="name">
</div>
<div class="form-group">
<label>email</label>
<input type="text" name="email">
</div>
<div class="form-group">
<label>message</label>
<input type="text" name="message">
</div>
<button type="submit">Submit</button>
</form>
<script type="text/javascript" src="https://s3.amazonaws.com/stacktodoapi/0_0_4/stacktodo_full.min.js"></script>
<script type="text/javascript">new window.stacktodo.ui.SlackForm(document.getElementById('s2do-form'), { form: '********-****-****-****-************' });</script>
Stacktodoの謎
Pricingのページが見つからないのですが…誰かご存知ならぜひ…でも、たぶんまだ無料で使えるっぽいです。
https://stacktodo.com
s3へアップロード
結構手順を端折っていますが、実際には一応今の状態でGithubのリポジトリにpushくらいはしています。あとはaws configure
済の環境でclone
してaws s3 cp --recursive
とかしてs3にアップロードしました。
s3上のsvgファイルのヘッダー情報がおかしい問題勃発
Hamburger Menuなどで一部svgファイルを使っているのですがどうもヘッダー情報がおかしい。mime content-typeにbinary/octet-stream
と表示されている。どうやってもimage/svg+xml
にならない。
s3にcpするときに--content-type image/svg+xml
を付ける
こんな感じである。
aws s3 cp --content-type image/svg+xml img/common/icon_fb.svg s3://{destination-s3-bucket}/img/common/
Header情報を確認するとこんな感じになっていればOK
-bash-4.2$ aws s3api head-object --bucket {destination-s3-bucket} --key img/common/icon_fb.svg
{
"AcceptRanges": "bytes",
"ContentType": "image/svg+xml", # ←ココ!!!
"LastModified": "Mon, 13 Feb 2017 13:26:30 GMT",
"ContentLength": 1092,
"ETag": "\"********************************\"",
"Metadata": {}
}
CSSのbackground-image url()をcloudfrontに向ける
これを以下の様に直す。
.btn--facebook {
- background-image: url(../../img/common/icon_fb.svg);
+ background-image: url(https://{your-cloudfront-url}/img/common/icon_fb.svg);
}
s3上のsvgファイルを公開する
Chrome Developers Consoleを見ると403 forbidden
になったりしていた。なのでs3で対象のsvgファイルを公開にすることで解決できた。
naked domainの対応
sslなしでnaked domainにアクセスするとこんなん(Bad Request The request could not be satisfied.)出てますよっていうご指摘をいただきました。
おっといけねぇということで別途naked domain用にs3 bucketを作ってStatic website hostingの部分でリダイレクト設定を以下のように行いました。
後はRoute53のnaked domainのAレコードをこのs3 bucketに向ければOKです。お騒がせしました
ということでお疲れさまでした。
これで無事にリリースできました。これであなたも快適なs3 + cloudfront + Stacktodoライフ(だからなに)をおくれますね
https://www.elevennines.co.jp
-
DNSはRoute53を向いているという前提で… ↩