はじめに
(インフラエンジニアが個人開発しています→https://kondate-loop.com/)
個人開発や小規模チームでAWSを触り始めると、最初に迷うのが「どこまで本格的にやるか」だと思います。
ECS も RDS も VPC も全部きちんとやる、という方向ももちろんあります。ただ、最初の一歩としては、荷が重い。。
そこで今回は、なるべく最小構成に寄せた AWS 構成でアプリを組んでみました。
狙いは、まずは「配信できる」「APIが動く」「認証できる」「データを持てる」「デプロイできる」までを、なるべく少ない要素で構築することです。
CloudFormation を使った理由は、ぶっちゃけ普段の仕事で使っててなれているからです。
正直、今から新しく始めるなら Terraform の方がよい場面もあると思っています。ただ、まずは自分が扱いやすい道具で最小構成を一度通す方が、個人開発では前に進みやすいとも感じています。
今回の構成
今回の構成はかなりシンプルです。フロントエンドの静的配信は CloudFront + S3、バックエンドは API Gateway + Lambda、データストアは DynamoDB、認証は Cognito、画像置き場は S3 に寄せています。
CloudFront は静的配信だけでなく、/v1/*、/auth/*、/share/* を API Gateway 側へ振り分ける入口にもしています。CloudFormation のテンプレートは2つ作成していて、1つ目はインフラスタックでCloudFront/S3 を、2つ目はバックエンドスタックとして API Gateway/Lambda/DynamoDB/Cognito/S3 を作成する分け方にしました
この構成のよいところは、責務がかなり素直なことです。
静的ファイルは S3 から配る、API は Lambda で受ける、認証は Cognito に任せる、データは DynamoDB に置く。これだけでも、AWS で Web アプリを動かすうえで必要な主要要素は一通り触れます。
デプロイ / CI/CD 構成
CI/CD もできるだけ単純にしています。
GitHub Actions から AWS に入り、バックエンドの成果物は S3 に置いたうえで CloudFormation で stack を更新し、フロントエンドはビルド後に S3 へ同期して CloudFront のキャッシュを invalidate する構成です。workflow は feature/**、dev、main をトリガーにしており、feature/dev では backend 側、dev ではさらに frontend 側、main では prod 側を動かす流れになっています。(詳しくはこちら→https://qiita.com/yuuka_n/items/3825fb1bbf09317951c8)GitHub Actions では OIDC を使って AWS 認証情報を設定しています。
ここでも意識したのは、デプロイの導線を増やしすぎないことです。
ローカルから直接いろいろ叩けるようにするより、まずは GitHub Actions に寄せてしまった方が、「どこから変更が入ったか」を追いやすくなります。
CloudFormation を選んだ理由
CloudFormation は、AWS リソースを YAML / JSON のテンプレートで記述し、stack という単位でまとめて作成・更新・削除できる AWS の IaC サービスです。AWS 公式でも、テンプレートに書いた AWS リソースを CloudFormation がまとめてプロビジョニングし、stack 単位で管理する仕組みとして説明されています。 (AWS Documentation)
今回 CloudFormation を選んだ一番大きい理由は、冒頭でも書いた通り、仕事で使っていて慣れているからです。
個人開発では、ツール選定で悩み続けるより、まずは手が動くもので最後まで通した方が得られる学びが大きいことがあります。今回はその判断でした。
加えて、AWS だけで完結する小さめの構成なら、CloudFormation が便利だと思います。AWS の Prescriptive Guidance でも、CloudFormation は state を AWS 側で管理し、change sets や rollback などの仕組みを持つことが利点として挙げられています。また、AWS 上だけを管理するなら CloudFormation や CDK はよい選択肢だと整理されています。 (AWS Documentation)
初心者向けという観点でも、CloudFormation は悪くないと思っています。
AWSネイティブなので、コンソール・CLI・ドキュメントの文脈が揃いやすく、まずは「テンプレートを書く → stack を作る」という基本に集中しやすいからです。 (AWS Documentation)
Terraform はどうなのか
ただし、CloudFormation が唯一の正解だとは思っていません。
Terraform は、クラウドやオンプレミスのリソースを人が読みやすい設定ファイルで管理でき、provider を通じて多くのサービスやプラットフォームを扱えるのが強みです。HashiCorp の公式ドキュメントでも、Terraform は cloud / on-prem resources を定義して管理でき、providers によってさまざまな API と連携できると説明されています。 (HashiCorp Developer)
AWS 側のガイダンスでも、マルチクラウドやハイブリッドクラウドを見据えるなら Terraform が向く、一方で AWS に閉じた構成なら CloudFormation / CDK が自然、という整理になっています。なので、今後この構成が大きくなって、AWS 以外のサービスもまとめて IaC 管理したくなったら、Terraform を本格的に検討する余地は十分あると思っています。 (AWS Documentation)
一方で、Terraform は state の扱いを明示的に意識する必要があります。AWS のガイダンスでは、Terraform は CloudFormation のように state を自動管理しないため、remote state の保存先や保護も考える必要があると説明されています。AWS だけの最小構成を一人で始める段階では、この差は思ったより大きいです。 (AWS Documentation)
というあれやを踏まえて、自分的な感触はこんなです↓
CloudFormation は、AWS に寄せて最小構成を素早く形にしたいときに相性がいい。
Terraform は、将来的に管理対象を広げたいときに検討価値が高い。
どちらが絶対に正しい、ではなく、今のフェーズと目的で選ぶのがよいと思っています。 (AWS Documentation)
まとめ
今回の構成は、CloudFront + S3 で静的配信、API Gateway + Lambda で API、DynamoDB でデータ管理、Cognito で認証、S3 で画像保管、GitHub Actions + CloudFormation でデプロイという、かなり最小寄りの AWS 構成です。実装上もその役割分担でテンプレートと workflow を分けています。
もっと本格的な構成はいくらでもあります。
ただ、AWS初心者や個人開発の最初の一歩としては、まずこのくらいの最小構成で全体を理解できることの価値はかなり大きいと思っています。
CloudFormation を選んだのは、仕事で使っていて手に馴染んでいたからです。
でもそれは「CloudFormation じゃないといやだ!」という意味ではありません。今の自分にはこれが扱いやすかった、というだけです。将来的には Terraform も含めて、構成の規模や運用の広がりに合わせて見直していきたいです (AWS Documentation)
それでも、AWSでインフラ構築を学び始める段階では、最小構成で一度最後まで作ってデプロイしてみるのが、いちばん理解が深まるやり方だと思っています。

