最近、@jiro4989さんの「テキストを壱百満天原サロメお嬢様風の口調に変換するアプリ」がバズっている。
何ならWeb版も公開くださっていて、ワイのようなへっぽこインフラエンジニアがコントリビュート出来ることは特にないのだが、自身の勉強のためにAWSを使ってこいつにJSONを投げつけるWeb画面を構築してみた。
おそらくAWSで独自ドメインを使ってWebサイトをホスティングしたり、バックエンドにAPIを利用する際に流用しやすいパターンな気がするので、構成図や構築手順を簡単に残してみる。
今回作ったもの
こいつ
つくりかた
1. API Gatewayのリソースを作成
公式Readmeを見ると、ojosama-web APIは Text
キーに文字列を入れたJSONを投げてやると、 Result
キーに翻訳結果が入れられて返ってくるREST APIである模様。
$ curl -X POST -H 'Content-Type: application/json' -d '{"Text":"これはハーブです!"}' https://ojosama.herokuapp.com/api/ojosama
{"Result":"これはおハーブですわ~!"}
以下の記事を参考に、POSTリクエスト用のAPIを作成してみる。
AWSマネジメントコンソールより新規REST APIを作成し、POST先として https://ojosama.herokuapp.com/api/ojosama
を指定。
試しにコンソール上からPOSTメソッドテストでリクエスト本文に {"Text":"これはハーブです!"}
を指定してみて、 {"Result": "これはおハーブですわ!!"}
がレスポンス本文に返ってきたら成功。
また、リソースのアクションより「CORSの有効化」を実施する。設定内容はデフォルトのままでOK。
これを prd
ステージにデプロイしておく。
2. S3でHTML画面をホスティング
ここから先の流れは以下のクラメソさんブログで非常に分かりやすくまとめてくれているので、参考にさせていただいた。
まずS3コンソールから今回ホスティングに利用するバケットを作成。
CloudFront経由でOAI(オリジンアクセスアイデンティティ)を利用したアクセスを提供するため、バケット自体のパブリックアクセス設定はブロックのままでも問題なし。
また、バケットのCORS設定に以下を追加しておく。
[
{
"AllowedHeaders": [
"Authorization"
],
"AllowedMethods": [
"GET"
],
"AllowedOrigins": [
"https://********.execute-api.ap-northeast-1.amazonaws.com/prd" ★API GatewayのエンドポイントURLを記載する
],
"ExposeHeaders": [],
"MaxAgeSeconds": 3000
}
]
このバケットに画面用のHTMLファイルを放り込む。
コードは以下の記事を参考にさせていただいた。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>変換ですわ!</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$("#response").html("(ここに結果が表示されます)");
$("#button").click( function(){
var url = "https://********.execute-api.ap-northeast-1.amazonaws.com/prd"; //API GatewayのエンドポイントURLを記載する
var JSONdata = {
"Text": String($("#value1").val())
};
$.ajax({
type : 'post',
url : url,
data : JSON.stringify(JSONdata),
contentType: 'application/json',
dataType : 'json',
scriptCharset: 'utf-8',
success : function(data) {
$("#response").html(JSON.stringify(data));
},
error : function(data) {
// Error
alert("error");
alert(JSON.stringify(data));
$("#response").html(JSON.stringify(data));
}
});
})
})
</script>
</head>
<body>
<h1>お嬢様言葉に変換しますわ!<br>Webフロントエンド by みのるん</h1>
<p>変換したい文章: <input type="text" id="value1" size="50" value="これはハーブです"></p>
<p><button id="button" type="button">変換ですわ!</button></p>
<textarea id="response" cols=50 rows=5 disabled></textarea>
<br><br><br><br>
<p>最近バズってる以下のWebアプリに<br>JSONリクエストを飛ばすためのフロントエンドです。<br></p>
<a href="https://github.com/jiro4989/ojosama-web">https://github.com/jiro4989/ojosama-web</a>
<br><br>
<p>AWSのCloudFront+S3+API Gatewayで構築しています。</p>
<br><br>
<font color="gray"><p>※本プログラムは<a href="https://github.com/jiro4989">jiro4989</a>様、ならびに<a href="https://event.nijisanji.app/guidelines/">ANYCOLOR</a>様提示の<br>
注意事項ならびにガイドラインに則り公開しています。</p></font>
</body>
</html>
こいつに index.html
という名前を付けて、バケットのルートに配置しておく。
そしてバケットの静的ウェブサイトホスティング設定を有効にすると、このHTMLファイルをWebサーバー不要で外部公開してくれる。
3. CloudFrontでWebサイトを公開
お次はCloudFrontで上記Webサイトを配信する。
これによってS3バケットへのアクセスポイントを限定できる他、エンドユーザーの近くのエッジロケーションにコンテンツをキャッシュさせたり、独自ドメインを利用してカスタムURLからセキュアなアクセスを実現したりということが可能となる。
CloudFrontコンソールからWebディストリビューションを作成し、オリジンドメイン名にS3バケット名を指定。S3バケットへのアクセス制限を有効にしておく。
4. ACMで証明書を発行し独自ドメインURLを適用
ACM(Amazon Certificate Manager)コンソールより証明書の作成を実施。Amazon発行のパブリック証明書をリクエストする。
今回、私の場合は既にお名前.comで取得済みのドメインを利用するが、ドメインを持っていない人はRoute 53の機能でAWSコンソール内で独自ドメインを取得してしまうことも可能。これは便利。
ACMで発行するパブリック証明書のFQDN名は、自分のドメインにサブドメインを付けてもよい。私の場合は cloudfront.minoruonda.com
とする。
作成者が正規のドメイン管理者であることを確認するため、確認用にDNSサーバーへCNAMEレコードを設定してみよとの課題が出される。
お名前.comのDNSレコード設定画面より、CNAMEレコードを登録。
ACMが「発行済み」ステータスへ変われば完了。
その後、CloudFrontディストリビューションの代替ドメイン名へ今回設定したサブドメインを指定し、SSL証明書にもカスタム証明書を指定する。
動作確認
今回作成した https://サブドメイン.独自ドメイン/index.html
へWebブラウザーからアクセスしてみる。
フロント画面が無事に表示され、ボタンを押すと変換結果がフォーム内に表示されればOK!
(レスポンスのJSONがそのまま表示されちゃうダサい仕様なのはご愛嬌。コード改善したくなった方は本記事へのプルリクお待ちしてます!)
おわりに
今回の構築ではCloudFront+ACM+S3+API Gatewayの設定を通して、各AWSサービスの基礎知識に加えてDNSやSSL証明書、REST API、HTML/JS、CORSなどそこそこ多様なレイヤーのIT基礎知識が身につくため、意外とよい勉強材料だった。
※今回の工程の一部は、私の環境では結構前に設定済みのものを含んでいたので、実機を見つつ思い出しながら執筆しています。もし不備等あればお知らせいただけると幸いです!