「私のコードは完璧なのに、なぜサーバーでは動かないのですか?」 — 数多くの開発者の最初のデプロイ経験談
🎯 この記事で扱うこと
- 開発者がインフラを知らない場合に発生する実際の問題
- DevOps、IaC(Infrastructure as Code)がなぜ開発者の領域になったのか
- インフラ知識がコード品質自体を変える理由
- クラウド時代に開発者が最低限知るべきインフラ概念
- 実務で即活用できるTerraform + GitHub Actionsの例
📌 導入 / 背景

10年前まで、開発者と運用者の役割は明確に分かれていました。開発者はコードを書き、運用チーム(Ops)はサーバーにデプロイするという形でした。開発者がインフラを知らなくても仕事は回っていました。
しかし、今は違います。
クラウドが普及し、マイクロサービスアーキテクチャが標準となるにつれて、インフラ自体がコードで管理されるようになりました。AWS、Azure、GCPのようなクラウドプラットフォームは、数クリックでサーバーを作成できるようにしましたが、同時にその責任も開発者に多く移ってきました。
現実を直視しましょう。
- スタートアップでは、インフラ専任チームがいない場合がほとんどです。
- 大企業でもDevOps文化が定着し、開発者が直接パイプラインを管理しています。
- 「それは運用チームの仕事です」と言って、デプロイが2週間も遅れる現実を経験した方も多いでしょう。😅
開発者がインフラを理解すべき時代、その理由を一つずつ解説していきます。

🔍 理由 1: コードは環境に乗って流れる
開発環境(Local)、テスト環境(Staging)、運用環境(Production) — これら3つの環境が異なると、何が起こるでしょうか?
古典的な開発者の悪夢が繰り広げられます。
「私のローカルでは動きます。」
この言葉がなぜ出てくるのかを考えると、結局は環境設定の違いが原因です。ローカルはPython 3.11なのにサーバーは3.9を使っている、環境変数が異なって設定されている、データベースの接続方法が違う、などです。
これを解決する主要なツールがDockerとコンテナです。コンテナは「私のコード + 実行環境」を一つのまとまりとしてパッケージ化し、どこでも同じように実行されることを保証します。
開発者がDockerfileを直接作成し、管理できる必要がある理由はここにあります。運用チームに「環境を合わせてください」と依頼するのではなく、自分のコードがどのような環境で動作するのかを自分で直接定義できる必要があります。
# 例: Python WebアプリのDockerfile
FROM python:3.11-slim
WORKDIR /app
# 依存関係を先にコピー (キャッシュ活用)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# ソースをコピー
COPY . .
# ポートを公開
EXPOSE 8000
# 実行コマンド
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
このファイル一つで、「Python 3.11環境で、これらのパッケージをインストールして、このように実行せよ」を明確に定義します。運用チームも、同僚の開発者も、CI/CDパイプラインも同じように理解します。🎯
🔍 理由 2: インフラを知らないとコードが非効率になる
インフラ知識のない開発者がよく犯す間違いを考えてみましょう。
💸 不要なリソースの浪費
APIリクエストごとにDBコネクションを新しく確立して閉じるコードを作成するとどうなるでしょうか?トラフィックが集中した瞬間にDBがコネクション数制限にかかり、ダウンします。コネクションプール(Connection Pool)の概念を知っていれば、最初からこのようなコードは書きません。
🐌 不要なネットワークホップ
マイクロサービス環境でサービスAがBを呼び出し、BがCを呼び出す構造を設計する際 — 同じVPC(仮想プライベートネットワーク)内に配置すればレイテンシは1ms未満ですが、外部インターネットを経由すると100ms以上に跳ね上がることがあります。ネットワークトポロジを理解する開発者は、アーキテクチャ設計段階でこれを考慮します。
💣 ハードコーディングされた設定値
# 悪い例 — 絶対にこのようにしてはいけません
DB_HOST = "192.168.1.100"
DB_PASSWORD = "mypassword123" # 😱
# 良い例 — 環境変数で分離
import os
DB_HOST = os.getenv("DB_HOST")
DB_PASSWORD = os.getenv("DB_PASSWORD")
インフラを理解する開発者は、設定値が環境ごとに異なることを知っています。そのため、最初から環境変数、Kubernetes Secrets、Azure Key Vaultのような秘密管理ツールを考慮してコードを作成します。
🔍 理由 3: IaC(Infrastructure as Code) — インフラも今やコードだ
IaCとは、サーバー作成・ネットワーク設定・ファイアウォールルールなどのインフラ構成を、クリックではなくコードファイルで定義する方式です。
なぜ重要なのでしょうか?考えてみてください。
- サーバーをコンソールで手動で作成した場合、後で「このサーバーはどうやって作ったんだっけ?」を知ることはできません。
- コードで定義すればGitでバージョン管理ができます。誰が、いつ、なぜ変更したのか追跡可能です。
- 同じ環境を10個作成する必要がある場合?コードを一度実行するだけで済みます。
代表的なIaCツールがTerraformです。
# Azureにリソースグループと仮想マシンを作成するTerraformの例
provider "azurerm" {
features {}
}
# リソースグループを作成
resource "azurerm_resource_group" "example" {
name = "my-app-rg"
location = "Korea Central"
}
# 仮想ネットワークを作成
resource "azurerm_virtual_network" "example" {
name = "my-app-vnet"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
}
このコードファイルがインフラの設計図そのものです。開発者がこのファイルを読み書きできれば、インフラチームとのコミュニケーションコストが劇的に削減されます。
🔍 理由 4: CI/CDパイプライン — デプロイ自動化の主導権
CI/CDは、コード変更が発生すると自動的にテストし、デプロイまで行うパイプラインです。
- CI (Continuous Integration): コードを統合しながら自動的にビルド・テスト
- CD (Continuous Delivery/Deployment): テスト通過時に自動的にステージングまたは運用環境にデプロイ
このパイプラインを誰が作成し、管理するのでしょうか?以前はDevOpsエンジニアの専任領域でしたが、今は開発者が直接作成するケースが多くなっています。GitHub Actions、GitLab CI、Azure DevOpsのようなツールがコードベースでパイプラインを定義するためです。
# GitHub Actions — PR作成時の自動テスト + Azureデプロイの例
name: Deploy to Azure
on:
push:
branches: [main]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
# コードをチェックアウト
- uses: actions/checkout@v3
# Dockerイメージをビルド
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
# Azureログイン (マネージドIDまたはサービスプリンシパルを活用)
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
# Azure Container Registryにプッシュ
- name: Push to ACR
run: |
az acr login --name myregistry
docker tag myapp:${{ github.sha }} myregistry.azurecr.io/myapp:latest
docker push myregistry.azurecr.io/myapp:latest
# Azure App Serviceにデプロイ
- name: Deploy to App Service
run: |
az webapp config container set
--name my-web-app
--resource-group my-app-rg
--docker-custom-image-name myregistry.azurecr.io/myapp:latest
このYAMLファイルを読み書きできる開発者は、デプロイプロセスを自ら制御できます。デプロイが滞ったときに運用チームを待つ必要はありません。🚀
🔍 理由 5: セキュリティは開発段階から始まる
インフラを知らない開発者がよく見落とすことの一つがセキュリティ設定です。
例えば:
- S3バケット(ファイルストレージ)を作成する際にパブリックアクセスを許可してしまうミス → 顧客データ漏洩事故
- 開発の便宜上、ファイアウォールポートを全開放(0.0.0.0/0) → 外部攻撃に晒される
- ログにパスワードやAPIキーを出力 → ログ収集ツールを介した情報漏洩
Shift Left Security(セキュリティの左シフト)という概念があります。セキュリティレビューをデプロイ後ではなく、開発段階から適用しようという方向性です。開発者がインフラセキュリティの概念を理解して初めて可能なことです。
最小権限の原則(Principle of Least Privilege)、ネットワーク隔離、秘密管理 — これらの概念がコード設計段階で反映されるべきです。
⚠️ 注意事項 / よくある間違い
① インフラ学習を「後で」に先延ばしすること 「まずはコードをうまく書くのが先」という考えは正しいですが、インフラ知識はコード設計自体に影響を与えます。後で学ぼうとすると、既存のコードを大規模にリファクタリングしなければならない状況になります。
② クラウドコンソールだけに依存すること GUIでサーバーを作成する練習だけでは、自動化や再現性がありません。最初からCLIまたはIaCツールで慣れる習慣をつけましょう。
③ コスト感覚なしにリソースをプロビジョニングすること 開発テスト中に高性能VMを起動したまま忘れると料金が請求されます😅。クラウドは便利ですが、コスト爆弾には注意が必要です。必ず予算アラート(Budget Alert)を設定しましょう。
④ 「DevOpsはDevOpsエンジニアがやること」という固定観念 役割の境界はますます曖昧になっています。特にスタートアップや小規模チームでは、開発者がインフラまで扱うのが基本値に近いです。
✅ まとめ / 締めくくり
開発者がインフラデプロイを知るべき理由をまとめると以下のようになります。
| 理由 | 核心内容 |
| 環境の一貫性 | Dockerで実行環境をコード化し、「私のローカルでしか動きません」から脱却 |
| コード品質 | ネットワーク、DB構造を知ることで、より効率的なコード作成が可能に |
| IaC | インフラもGitで管理する時代、Terraformは選択ではなく教養 |
| CI/CD | デプロイパイプラインを自ら設計・運用できてこそ真の自律性 |
| セキュリティ | セキュリティはデプロイ後ではなく開発段階から — Shift Left |
インフラデプロイを「DevOpsエンジニアの仕事」とだけ考える時代は終わりました。クラウドネイティブ環境において、開発者はコードとインフラの境界を自由に越えられなければなりません。
最初からすべてを知る必要はありません。Docker → GitHub Actions → Terraformの順に一つずつ経験してみてください。デプロイを直接経験した開発者とそうでない開発者では、コード品質が明らかに異なります。💪
コメントを残す