"내 코드는 완벽한데, 왜 서버에서는 안 되죠?" — 수많은 개발자들의 첫 번째 배포 경험담
🎯 이 글에서 다루는 것
- 개발자가 인프라를 모르면 생기는 실제 문제들
- DevOps, IaC(Infrastructure as Code)가 왜 개발자의 영역이 됐는지
- 인프라 지식이 코드 품질 자체를 바꾸는 이유
- 클라우드 시대에 개발자가 최소한 알아야 할 인프라 개념
- 실무에서 바로 써먹는 Terraform + GitHub Actions 예시
📌 도입 / 배경

10년 전만 해도 개발자와 운영자의 역할은 칼같이 나뉘어 있었습니다. 개발자는 코드를 작성하고, 운영팀(Ops)은 서버에 올리는 식이었죠. 개발자가 인프라를 몰라도 일이 돌아갔습니다.
그런데 지금은 다릅니다.
클라우드가 보편화되고, 마이크로서비스 아키텍처가 표준이 되면서 인프라 자체가 코드로 관리되기 시작했습니다. AWS, Azure, GCP 같은 클라우드 플랫폼은 클릭 몇 번으로 서버를 만들 수 있게 해줬고, 동시에 그 책임도 개발자에게 많이 넘어왔습니다.
현실을 직시해봅시다.
- 스타트업에서는 인프라 전담 팀이 없는 경우가 태반입니다.
- 대기업도 DevOps 문화가 자리잡으면서 개발자가 직접 파이프라인을 관리합니다.
- "그건 운영팀 일이에요"라고 했다가 배포가 2주씩 밀리는 현실을 경험한 분들 많으실 겁니다. 😅
개발자가 인프라를 이해해야 하는 시대, 그 이유를 하나씩 풀어보겠습니다.

🔍 이유 1: 코드는 환경을 타고 흐른다
개발 환경(Local), 테스트 환경(Staging), 운영 환경(Production) — 이 세 가지 환경이 다르면 어떤 일이 벌어질까요?
고전적인 개발자의 악몽이 펼쳐집니다.
"제 로컬에서는 잘 돼요."
이 말이 왜 나오는지 생각해보면, 결국 환경 설정의 차이 때문입니다. 로컬은 Python 3.11인데 서버는 3.9를 쓰고 있다거나, 환경 변수가 다르게 설정돼 있다거나, 데이터베이스 연결 방식이 다르다거나.
이걸 해결하는 핵심 도구가 바로 Docker와 컨테이너입니다. 컨테이너는 "내 코드 + 실행 환경"을 한 묶음으로 포장해서 어디서든 동일하게 실행되도록 보장합니다.
개발자가 Dockerfile을 직접 작성하고 관리할 수 있어야 하는 이유가 여기 있습니다. 운영팀에게 "환경 맞춰주세요"를 요청할 게 아니라, 내 코드가 어떤 환경에서 동작하는지 내가 직접 정의할 수 있어야 합니다.
# 예시: Python 웹앱 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 로그인 (Managed Identity 또는 Service Principal 활용)
- 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 순서로 하나씩 경험해보세요. 배포를 직접 해본 개발자와 그렇지 않은 개발자의 코드 품질은 분명히 달라집니다. 💪
'클라우드' 카테고리의 다른 글
| 🍀 HashiCorp가 배신했다? — Terraform의 역사와 OpenTofu가 탄생한 진짜 이유 (0) | 2026.03.28 |
|---|---|
| 🥊 AWS Image Builder vs Packer — 실무 DevOps 엔지니어라면 뭘 써야 할까? (0) | 2026.03.27 |
| ☁️ AWS 마이그레이션할 때 왜 AWS 콘솔 말고 테라폼을 배워야 하나? (0) | 2026.03.27 |
| 🔑 키 교체(Key Rotation)하면 데이터를 전부 다시 암호화할까? — 클라우드 KMS의 진실 (0) | 2026.03.27 |
| Mac에서 Podman으로 멀티 아키텍처(Intel & ARM) 이미지 한 번에 빌드하기 (0) | 2026.03.18 |