はじめに
こんにちは。
26新卒のむらのと申します。
現在、SAA(AWS認定ソリューションアーキテクト – アソシエイト)の取得に向けて学習しています。
AWS Summit楽しかったですね。
私は人生で2回目なのですが、いろいろなものがもらえるのと、技術的なものに詳しくなくても楽しめる場だと感じます。
(技術がわかったら2000倍くらい楽しいんだろうなあ、、、と思い今猛勉強をしております)
ここらで本題に入りましょう。
これまでに、
- インフラ系の学習で詰まって気づいた「完成形から逆算する」大切さ
- AWS CLFに合格するまでにやったこと
- AWSサービスを「例え」で整理した話
といった記事を書いてきました。
今回は、その総まとめのような内容です。
知識をインプットするだけではなく、
実際に自分で何か作って、デプロイしてみたい
と思い、AWSのサーバーレス構成で「短縮URLサービス」を作ってみました。
そして案の定、途中で詰まりました。
ただ、過去の自分の記事に書いた
「完成形から逆算する」
という考え方を実際に使って、無事に解決できました。
この記事では、
- 何を作ったか
- どんな構成にしたか
- どこで詰まったか
- どう解決したか
を、初学者目線でまとめます。
同じようにSAAを学習している方や、「インプットだけでは物足りない」と感じている方の参考になれば嬉しいです。
作ったもの:短縮URLサービス
今回作ったのは、よくある「短縮URLサービス」です。
- 長いURLを入力すると、短いURLに変換してくれる
- 短いURL(例:
/a3Xk9p)にアクセスすると、元のURLに飛ぶ
というシンプルなものです。
なぜこれを選んだかというと、
- 小さく完結する
- でもサーバーレスの主要サービスを一通り使える
- DynamoDBの使い方がきれいに学べる
という、学習にちょうどいい題材だと思ったからです。
どんな構成にしたか
今回はあえて、EC2を使わない「サーバーレス構成」にしました。
過去にEC2 + RDSの構成は触ったことがあったので、
前回と違う世界を体験したい
という気持ちもありました。
構成はこんな感じです。
【画面を見るとき】
ユーザー → CloudFront → S3(index.html)
【URLを短縮・リダイレクトするとき】
ユーザー → API Gateway → Lambda → DynamoDB
使ったサービスを、過去記事と同じく「役割」で整理するとこうなります。
| サービス | 今回の役割 | 例えるなら |
|---|---|---|
| S3 | 画面ファイル(index.html)を置く | 巨大な倉庫 |
| CloudFront | 倉庫の中身を安全に届ける窓口 | 全国の配送拠点 |
| API Gateway | リクエストを受け取る入口 | 受付窓口 |
| Lambda | 短縮・リダイレクトの処理をする | 必要な時だけ呼ばれるアルバイト |
| DynamoDB | 短縮コードと元URLを保存する | データの保管庫 |
「役割」で並べてみると、それぞれが何のためにいるのかが分かりやすくなりました。
こだわったポイント
DynamoDBはパーティションキー1本で引く
短縮URLは、
「短縮コードを渡されたら、対応する元URLを1件返す」
という使い方しかしません。
なので、テーブルは
- パーティションキー:
code(短縮コード)
の1本だけにしました。
JOINも検索もいらず、キー1本で必ず1件引ける。
これがDynamoDBの一番得意な使い方だと知って、なるほどと思いました。
S3は公開せず、CloudFront経由だけにする
最初は「S3を公開すればいいのでは?」と思っていました。
でも調べてみると、
- S3はブロックしたまま
- CloudFront経由(OAC)でだけ読めるようにする
というのが安全な作り方だと知りました。
これはSAAでもよく出てくる考え方らしく、
「倉庫の扉は閉めたまま、配送拠点を通してだけ荷物を出す」
みたいなイメージで理解しました。
IAMは最小権限にする
Lambdaに付ける権限も、
- shorten関数 → 書き込み(PutItem)だけ
- redirect関数 → 読み取り(GetItem)と更新(UpdateItem)だけ
というふうに、必要なものだけに絞りました。
dynamodb:* のように全部許可してしまうのは楽ですが、
「必要な分だけ渡す」
のが大事だと学びました。
そして、詰まった
一通り作り終えて、いよいよ動作確認です。
CloudFrontのURLにアクセスしてみました。
すると、画面が出ずに、こんなエラーが返ってきました。
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
</Error>
「アクセスが拒否された」と言われています。
正直、最初は
「S3の公開設定が間違ってるのかな?」
「OACの設定をミスったかな?」
「バケットポリシーが変なのかな?」
と、それっぽい場所を片っ端から疑っていました。
これはまさに、過去の自分が記事に書いた
「それっぽい場所を勘で当てにいっている状態」
そのものでした。
完成形から逆算して考えた
ここで、いったん手を止めました。
そして、自分が前に書いた記事を思い出しました。
エラー対応は「原因探し」ではなく「差分確認」
なので、まず
完成している状態とは何か
を整理することにしました。
「画面が表示される」が成功だとしたら、そのために必要な前提は何か。
- ① CloudFrontのデプロイが完了していること
- ② S3にアップしたファイル名が正確に
index.htmlであること - ③ CloudFrontの「デフォルトルートオブジェクト」が
index.htmlであること - ④ バケットポリシーがCloudFrontからの読み取りを許可していること
この4つを、1つずつ「今どうなっているか」と照らし合わせていきました。
すると、④のバケットポリシーは正しく設定されていました。
①のデプロイも完了していました。
切り分けのために、ファイルを直接指定してアクセスしてみました。
https://(CloudFrontのドメイン)/index.html
これで画面が出るかどうかで、原因の場所が絞れると考えたからです。
原因は「前提」のところにあった
結果として、原因は
エラーが出ている場所そのものではなく、その前提の部分
にありました。
/index.html を直接指定したら画面が表示されたので、
「ファイル自体は読めている」
「でもトップURLだと読めない」
ということが分かりました。
つまり、CloudFrontが「どのファイルをトップとして返すか」を分かっていなかった、ということです。
ここを直したら、無事に画面が表示され、短縮URLの作成もリダイレクトも動きました。
この経験で感じたこと
今回、エラーで詰まったとき、
以前の自分なら、ずっと「それっぽい場所」を勘で触り続けていたと思います。
でも今回は、
- まず完成形を言葉にする
- 必要な前提を洗い出す
- 今の状態と1つずつ照らし合わせる
- 差分が出たところを直す
という流れで進められました。
AccessDenied というエラー文だけを見ていたら、たぶんずっとS3の公開設定を疑い続けていました。
実際の原因は、もっと手前の「前提」のところにあったのです。
過去の自分が記事に書いた
「完成形から逆算する」
という考え方を、今回は実際の手を動かす場面で使えたのが、一番の収穫でした。
おわりに
今回は、サーバーレスな短縮URLサービスを作って、デプロイまでやってみました。
作る前は、
「サーバーレスってなんだか難しそう」
と思っていました。
でも、実際に手を動かすと、
- S3とCloudFrontの関係
- API GatewayとLambdaのつながり
- DynamoDBの使い方
- IAMの最小権限
といった、SAAで学ぶ内容が「体感」として理解できるようになりました。
そして、詰まったときも、過去の自分の学びに助けられました。
知識をインプットするだけでなく、
実際に作って、詰まって、自分で解決する
という経験は、想像以上に学びが多かったです。
SAA学習中の方で、もし「何か作ってみたいな」と思っている方がいたら、
小さくてもいいので一度デプロイまでやってみるのはおすすめです。
引き続き、SAA合格に向けて学習を続けていきます。
最後まで読んでいただき、ありがとうございました。

