構築から設計へ ─ RareTECHで学んだ“責務を分ける”という考え方

## はじめに
2024年5月にRareTECHというITスクールに入会してから、ちょうど1年が経ちました。
この1年間、私はエンジニア実務未経験ながらもハッカソンに参加し、インフラの設計・構築やバックエンドの開発を経験してきました。

特に入会から1ヵ月後に参加した初めてのハッカソンでは、右も左も分からない中で、インフラの担当として設計から構築までを初めて任され、大きな学びを得ました。
その後のハッカソンでは主にバックエンドを担当してきましたが、今回の4回目のハッカソンではインフラとバックエンドの両方を担当しています。

本記事では、この1年間で得た「構築」から「設計」への視点の変化を振り返り、特に“**責務をどう分けるか**”という設計上の考え方に焦点を当てて、経験と気づきを整理します。

## 初めてのインフラ構築経験 ～振り返り～
私が初めてインフラの設計・構築を担当したのは、RareTECHに入会してからわずか1か月後に参加した初めてのハッカソンでした。
テーマは「**チャットアプリ**」。
ユーザー数の増加を想定した構成が求められる中、インフラ担当として、構成図の作成・環境構築・デプロイまでを一貫して担いました。

当時の構成は、EC2・ALB・RDSを中心としたオーソドックスなWeb3層アーキテクチャでした。

当時の構成は以下の通りです：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3958955/d25d7b60-a6df-4c9b-9bd3-ba7389729b17.png)

:::note info
本構成のポイント
- EC2をマルチAZに配置し、Auto Scaling Groupで冗長化
- EC2にはDockerをインストールし、**Nginx + Flask** をマルチコンテナ構成で起動
- RDS（MySQL）は当初マルチAZ構成を検討（※実際はシングルAZで構築）
- ALBにはスティッキーセッションを設定し、ログイン状態を維持
- セッションマネージャーとVPCエンドポイント経由で、開発者がEC2にアクセス
- Route 53で独自ドメインを管理、ACMでSSL証明書を発行しHTTPS化
:::

以下が当時の構成で使用した主な技術スタックです：

**使用技術**
フロントエンド：HTML, CSS
バックエンド：Python（Flask）
インフラ：Docker, AWS

### 当時の設計思想と課題
インフラに関する知識がほとんどなかった当時の私は、「とにかく動く構成を作る」ことを目標に設計や構築を進めていました。
セキュリティやスケーラビリティ、運用性をそれなりに意識していたつもりでしたが、今振り返ると、その構成は“設計されたもの”というよりは、情報を組み合わせて形にしただけのものでした。

このとき初めて「設計とは何か？」を考えるきっかけを得ると同時に、
「動くこと」と「設計されていること」は全く別物であるという感覚が、自分の中に芽生え始めたのを覚えています。

## 構成の進化と設計の課題 ─ 責務は本当に分離できていたか？
1回目のハッカソンで経験した「とにかく動かすことを目指した構成」から約1年、今回の4回目のハッカソンでは、運用性・拡張性・責務分離を意識したインフラ構成を設計・構築しました。

特に今回は、Terraformを用いてECS on Fargateベースのインフラをコードで管理し、GitHub ActionsによるCI/CDやSecrets Managerによるセキュアな環境変数の管理、Datadogによる監視構成も実現。構成としては、これまでで最も処理ごとの責任範囲を意識したインフラ設計ができたと感じています。

実際の構成図が以下です：

![AWSアーキテクチャ図_20250601.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3958955/4ba506f0-715b-422f-a2ed-c1732c2f5283.png)

:::note info
本構成のポイント
- **フロントエンド（Next.js）**
    - next build で生成された静的ファイルを S3 にデプロイ
    - グローバル配信は CloudFront を経由
→ us-east-1 のACMで発行したSSL証明書を適用し、HTTPS対応
- **バックエンド：ECS on Fargate（FastAPIアプリ, DB Migration）**
    - アプリケーションは ECS on Fargate 上の常駐タスク（Service）で起動
    - Alembic を用いたDBマイグレーション処理は、本番環境に不要な常駐リソースを避けるため、FargateのRunTask機能を使って**一時的に起動するコンテナ**として分離
    - 常駐タスクと一時タスクを分けることで、処理の責務が明確になり、運用コストの削減やトラブル時の切り分けも容易になる
    - 東京リージョンのACMで発行したSSL証明書をALBに適用し、外部からのHTTPSリクエストを安全に受け付ける

- **共通構成**
  - ALBでHTTPS終端し、東京リージョン（ap-northeast-1）のACMで発行したSSL証明書を適用
  - Route 53 にてドメイン・サブドメインを一元管理し、以下のようにルーティング：
    - `example.com` → CloudFront（静的サイト）
    - `api.example.com` → ALB → ECS（FastAPI）
  - Secrets Manager による環境変数のセキュアな管理

- **CI/CD（GitHub Actionsで全自動化）**
  - **フロントエンド（Next.js）**  
    `main` ブランチにPush → ビルド → アーティファクト取得  
    → S3にデプロイ → CloudFrontキャッシュ自動無効化
  - **バックエンド（FastAPI）**  
    `main` or `develop` ブランチにPush → Dockerイメージをビルド  
    → ECRにPush → ECS Fargateへデプロイ

- **Terraformによるインフラ管理**
  - VPC、サブネット、ALB、ECSクラスター、RDS など、全インフラリソースをTerraformでコード管理
  - ECSタスク定義は用途ごとに明確に分離（例：`fastapi-app`, `db-migration`, `mysql-client`, `datadog-agent` など）
  - 機能単位で責務を切り分けた構成をTerraformで明示することで、構成の一貫性と再現性を確保
  - Secrets Managerとの連携や、マネージドサービス間のIAMロール・セキュリティグループ設計もTerraformで一元管理
:::

このように、インフラ構成の面では「**責務を明確に分離した設計**」が実現できていたと感じています。

以下が今回の構成で使用した主な技術スタックです：

**使用技術**
フロントエンド：Next.js, TypeScript, TailwindCSS
バックエンド：Python（FastAPI）
インフラ：Docker, AWS,  GitHub Actions, Terraform, Datadog

## 設計の転機 ─ “構築”から“分離“へ

今回のハッカソンでは、Terraformを用いてインフラ構成をコード管理する中で、**タスク定義や各種リソースを「目的ごとに明確に分ける」こと**を強く意識しました。

ただし、実際の構築作業でチームの開発メンバーに助けてもらいながら進めた部分もあり、私一人で完結できた構成ではありません。

それでも、役割の中で強く意識していたのは、「**何のためにそのリソースを作るのか**」「**どの処理をどこに分けるべきか**」という**責務設計の視点**でした。

たとえば以下のように、処理単位で目的を切り分けた構成を設計しました：

- 常駐タスク：`fastapi-app`（アプリ本体）
- 一時タスク：`db-migration`（マイグレーション用RunTask）
- 確認用途：`mysql-client`（接続確認用）
- 監視用途：`init-datadog`, `datadog-agent`（初期化・常駐）

これらは、単なるコンテナの違いではなく、「**それがどの場面でどう動作し、誰が保守するべきか**」という視点で設計されています。

このように構成を考える中で、「どう動かすか」だけでなく、

> **「何の責任をどこに持たせるか」という“設計”の考え方**

に初めて本格的に触れたと実感しました。

### コードで設計意図を伝える

Terraformで構成を記述する中では、命名の仕方やディレクトリの分け方も含めて、**コードベースで設計意図を表現すること**を意識しました。  
「誰が見ても目的が伝わる構成になっているか？」という観点で考えるようになったのは、これまでのハッカソンやチーム開発を通じて得た感覚です。
実際に、構成の分離や命名に工夫を入れることで、チーム内の認識合わせがスムーズになり、設計とは“動かすため”だけでなく、“伝えるため”の行為でもあるという実感を得ることができました。

## 分けて設計することの意味が見えてきた

今回のハッカソンで最も実感したのは、**「設計の段階で責任範囲を切り分けておくこと」が、後の開発や運用にどれほど大きな影響を与えるか**という点でした。

構成上では、ECSのタスク定義を用途ごとに分け、Secrets Managerの環境変数を明示的に管理し、RunTaskで一時的な処理を分離する──  
こうした「分ける設計」ができていたからこそ、チーム開発でも以下のような運用上のメリットを感じました：

- **誰が・どの処理を担当しているのかが明確になりやすい**  
  特定の処理が `db-migration` や `init-datadog` などに明示されているため、チームメンバーとの認識齟齬が起きにくい

- **障害時の原因調査がしやすい**  
  コンテナやタスク単位で切り分けられているため、「どの処理が失敗したのか」を構成レベルで把握しやすい

- **GitHub ActionsでのCI/CD設計にも責任が反映されやすい**  
  たとえば、デプロイ前にマイグレーションRunTaskを実行し、完了してからアプリタスクを切り替える、という処理が論理的に組みやすくなった

また、Terraformでこうした構成をコード化したことで、**設計意図がコードとして“残る”ことの価値**も強く感じました。

これは口頭やメモではなく、「**このタスクはこの目的で分けている**」という設計方針が、コードベースでチーム全体に共有されている状態です。

## 設計を通じて見えた変化 ─ 思考と関わり方の進化

RareTECHに入会してからの1年間で、私は「インフラを構築できるようになること」から「インフラをどう設計し、どう伝えるか」へと意識が変わっていきました。

最初のころは、「とにかく動く構成を作るにはどうすればいいか？」という視点で考えることが多く、技術的な組み立て方にばかり目が向いていました。  
しかし今では、「構成の意図は第三者にも伝わるか？」「後から見ても保守しやすいか？」といった、**設計そのものを“伝える行為”として捉える視点**が育ってきたと感じています。

特にTerraformでインフラをコード化したことで、命名やディレクトリ構成、リソースの分け方を通じて「**何のためにこの構成にしたのか**」を明確に示すことができました。

実務経験はまだありませんが、ハッカソンやチーム開発を通じて得たこの経験は、「設計とは、実装以前にまず考えるべき“整理と伝達の技術”である」という実感に結びついています。

これは単なる技術の習得ではなく、**「チームで作る」という前提のもと、自分の考えや意図を設計として形にし、伝える力を養った1年**だったと実感しています。

## おわりに

RareTECHでのこの1年間、私はフロントエンド・バックエンド・インフラ・セキュリティといった領域を横断的に学習しながら、チーム開発やハッカソンを通して「開発全体の流れとはどういうものか」に少しずつ触れてきました。

ただし正直に言えば、開発全体を俯瞰して設計できているとはまだ言えません。  
構成の意図をうまく言語化できなかったり、実装を進めながら設計の不備に気づいたりと、設計における課題は多く残っています。

構成の粒度や命名、責務分離の考え方にはまだブレがあり、  
「動く構成」は作れても、「伝わる設計」にはまだ遠い──そう感じる場面が多くありました。

:::note info
**今後の課題**

- **設計力の強化**  
  - タスク定義やモジュール設計の粒度を適切に保つ  
  - 複雑な要件を分解し、構成として落とし込む力を高める

- **設計意図の言語化**  
  - 「なぜこの構成にしたのか？」を明確に説明できるようにする  
  - チーム内での認識共有を意識したドキュメントの整備

- **全体像の把握**  
  - バックエンドとインフラの接続点、CI/CDのフローなど、処理の流れ全体を俯瞰して設計に活かせるようになる
:::

「設計」とは、ただ技術を組み合わせて構成を考えることではなく、  
**誰が・いつ・どのようにその構成を使うのかを想像して、それに合った形を選ぶこと**だと、少しずつ理解できてきました。

まだ設計力は足りていませんし、迷うことも多いです。  
でも、自分にとって何が課題で、何を意識していくべきかは見えてきた気がします。

まだまだ足りないことばかりですが、少しずつでも「設計」に向き合う意識が持てるようになった1年だったと思います。