1. はじめに
三月の末、苦心の末になんとかAWS SAAを取得した。
しかし実際のAWSには触れたことがなく、知識のみの頭でっかちな状況に危機感を感じ、
設計構築の学習を始めようとの決意。
せっかく作るなら、実生活に役立つものを作ろう。
その考えから、金銭勘定が苦手な自分を戒めるべく
カウントダウン式の家計簿を作ることに決定。
これは未経験エンジニアによる拙い奮闘の記録である。
本当にどこから手をつけていいかわからない状態だったので、
AI指導のもと作業するオペレータのような感じだった。
今回はチュートリアルとして割り切っている。
重視したのは操作の理解と実際の挙動、作って動かしたという実績を作ることだ。
Google Gemini先生ありがとう。
初めてということで、自分のためにできるだけ噛み砕いて説明してみる。
2. システムアーキテクチャの全体像
2-1. 前提
今回の要件として、
①お金がかからないこと
②とりあえず完成させること
③とりあえず動くこと
④メンテナンスが不要なこと
を意識した。
それを先生(Google Gemini)に伝え、検討した構成が以下だ。
2-2. 構成要素
-
フロントエンド:Amazon S3(静的Webサイトホスティング)
サーバ(webページを返す担当)の運用管理が必要なく、使った分だけ課金なのでEC2(サーバとして立てるやつ。起動している時間に応じて課金)に比べると今回の要件に合致するため。 -
バックエンドとの窓口:API Gateway(HTTP API)
REST API(なんか高機能なやつ)に比べてシンプルで安いらしい。詳しくはわからん。 -
:バックエンド処理(計算・仲介):AWS Lambda(Python 3.12)
これもS3と同じ理由。使った分だけ課金なので,EC2より今回の要件に合う。SAA勉強でサーバレスといえばこいつだった。さらにEC2だとサーバの管理が発生するのでなおさらLamda一択だった。Pythonにしたのはなんとなく聞いたことのある言語だったから。 -
データベース:Amazon DynamoDB
サーバレスと使った分だけ課金を実現するため。RDS(サーバを借りて作るDB)だと借りた分課金で管理の手間もかかる。キーバリューストア方式(識別子でデータを紐つけて保存する)なのもシンプルかつ早くて良いらしい。ほ〜ん。
3. 開発する中で起こったこと
先生の指示のもと、とりあえず全ての構成のセッティングを完了した。
SAAで培った知識でなんとなくやっていることは理解できたが、それだけだった。
知識と実践とはこんなに違うものかとまざまざと思い知らされた。
「現場を知らないエンジニアは使えない」
と少し前に上司に言われた言葉がフラッシュバックした。
千里の道も一歩からと、とりあえずの完成を目指した。
今回は操作に慣れることを至上目的としていたため、
コードはコピペで設定も言われるがままだ。
実際に組んでいく中で起こった、特に印象的だったことを以下に挙げる。
3-1. CORS(オリジン間リソース共有)の壁
S3のドメインからAPI Gatewayのドメインにブラウザ経由でアクセスした際、
セキュリティ制限(CORSエラー)によるブロックが発生。
調べてみると、API Gateway側の設定には CORS(Cross-Origin Resource Sharing)
というWebからの指示(Methods?)を判断する門番のような機能があるとのこと。
今回は「データを取得する」という命令は許可されていなかったらしい。
なんやそれ。SAAで習っとらんぞ。
急いでAPI Gateway側のCORS設定で、
Access-Control-Allow-Origin: *
MethodsにGET, OPTIONS
を許可することでブラウザの通信ブロックを解除して導通した。
3-2. DBに溜まっていく謎のデータ
なんとか動かせるようになり、ふとDynamoDBを覗くと
「0円・未分類」のデータがたくさん入っていた。
不思議に思い、先生に確認してみると、どうやらこれもCORSが関係しているようだ。
原因はデータの送信機能をフロント側に追加したことによるCORSエラーだった。
先生曰く、データの取得は「GET」というメソッドで、
データの送信は「POST」は別の命令らしい。
3−1で許可したのは「GET」のみだった。当然門番はエラーを返す。
しかし、実際には通信がバックエンドのLambdaまで届いていた。
プログラムの初期値は中身が空っぽの通信を受け取って動作し、
「0円・未分類」格納してしまっていた。
LambdaはAPI Gatewayにそれを返す。
でも「POST」が許可されていないためフロント側にはエラーとして表出する。
そんな仕組みでフロント側で実行するたびに
「0円・未分類」のデータが格納されるポンコツ家計簿が出来上がってしまった。
この後急いでAPI Gatewayを修正し「POST」も許可するようにした。
Lambda側も修正し、中身が空っぽの通信の時は何もしないようにした(してもらった)。
(なんか「バリデーション」やら「ガード条件」とやらを組み込んだらしい。要勉強)
〜以下先生によるわかりやすい3-2の事象のまとめ〜
- 【行き】:ブラウザから放たれた「POST」のデータは、実は門番をすり抜けて、裏側のLambdaまで一旦届いてしまっていた。
- 【Lambdaの動作】:URL設定のズレのせいで中身が空っぽのまま届いた通信に対し、Lambdaのプログラム初期値が優しく(?)発動。「0円・未分類」としてDynamoDBにデータを正常に保存してしまった。
- 【帰り】:処理を終えたLambdaが「終わったよ」と結果を戻した瞬間、API Gatewayが「あ、POSTのCORS設定がないからブラウザには返せないや」と通信を遮断した。
3-3. Terraform導入とルートユーザの恐怖
一通り機能は完成したので、IaC(Infra as Code)の勉強として
DynamoとLambdaのデプロイだけやってみた。
Terraformでのインフラのコード化にはAWSのアクセスキーが必要らしい。
おっしゃアクセスキー発行するで!
と勇み足で設定画面に行ったところ、「ベストプラクティスに反します」という旨の警告が。
どうやら今までの操作は
「ルートユーザ」という最上位の権限アカウントで実行していたらしい。
最上位ということはこれが乗っ取られたら全ての権限が使われ放題になってしまう。
恐ろしや。現場でやっていたらボスにボコボコにされていただろう。
最小権限の原則もへったくれもあったもんじゃない。
急いでTerraform用のアカウントと、操作用のAdminユーザをIAMで作成し、
ログインし直した。
SAAで学習したはずのことが実践となるとすっかり抜けてしまう恐怖を味わった。
4. AWSを使ってみての感想
4-1. AWSってこんな感じなんか
まずこんなに文面ベースで二次元的なUIだと思わなかった。
ずっとPCの設定をいじっているみたいな気持ちだった。
AWSって言葉に夢を見ていたようだ。
予算設定でアラートかけてはいるけど、
どこが課金ポイントなのかわからなくてビクビクしながら設定していた。
一番最初にぶち当たったのはリージョンの壁だ。
半分くらい組み終わった後に自分のリージョンが
米国東部(バージニア北部)なことに気がついた。どこやねん。
勝手にデフォルトは東京なもんだと思っていたからびっくりした。
泣く泣く全部消して東京に作り直した。苦い経験となった。
4-2. コードが読めねぇ
ITに携わって2年。運用の業務しかしておらずコードを扱ったことがない。
自慢ではないが基本情報技術者試験では科目Bのせいで2回辛酸を嘗めた。
今回の開発ではLambdaとS3に配置するhtml、IaCの際とコードを扱う場面があった。
全て先生による生成で賄った。が流石に危機感を覚えた。
URLの綴りによるエラーすらも自力で解決できないのが悔しかった。
AIに頼ってしまう今の地力の無さ、
そして頼れば解決出来てしまう状況が恐ろしいと思った。
5. おわりに
実際に触ってみて、知識と実践の恐ろしいほどの乖離を体験した。
わからないことだらけだったが、
いろんな失敗を体験できて非常に有意義な学習だったと思う.
実際に動作したアプリは
入力の修正もできず機能の不足が目立つ不完全なものなので載せることは避ける。
(素人作成のものなのでセキュリティ的にも怖い。)
次は認証機能(cognitoなど)を搭載したアプリの設計構築に取り組んでいこうと思う。
完成したらまとめとしてまた載せようと思う。
ありがとうございました。