🔧
DevOps
IaC
Infrastructure as Code
인프라를 코드로 정의하고 관리하는 방식. Terraform, Pulumi, CloudFormation 사용.
Infrastructure as Code
인프라를 코드로 정의하고 관리하는 방식. Terraform, Pulumi, CloudFormation 사용.
IaC(Infrastructure as Code)는 인프라를 코드로 정의하고 관리하는 방식입니다. 수동으로 콘솔을 클릭하는 대신, 선언적 또는 명령적 코드로 서버, 네트워크, 데이터베이스 등의 인프라를 프로비저닝합니다. 버전 관리, 코드 리뷰, 자동화된 테스트가 가능해져 인프라 관리가 소프트웨어 개발처럼 됩니다.
# main.tf - AWS VPC와 EC2 인스턴스
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "ap-northeast-2"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
provider "aws" {
region = var.region
default_tags {
tags = {
Environment = var.environment
ManagedBy = "Terraform"
}
}
}
# VPC
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.1.0"
name = "${var.project}-vpc"
cidr = "10.0.0.0/16"
azs = ["ap-northeast-2a", "ap-northeast-2c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
enable_nat_gateway = true
single_nat_gateway = var.environment != "production"
tags = {
Project = var.project
}
}
# Security Group
resource "aws_security_group" "web" {
name = "${var.project}-web-sg"
description = "Security group for web servers"
vpc_id = module.vpc.vpc_id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "${var.project}-web-sg"
}
}
# EC2 Instance
resource "aws_instance" "web" {
count = var.instance_count
ami = data.aws_ami.amazon_linux.id
instance_type = var.instance_type
subnet_id = module.vpc.private_subnets[count.index % length(module.vpc.private_subnets)]
vpc_security_group_ids = [aws_security_group.web.id]
root_block_device {
volume_size = 20
volume_type = "gp3"
encrypted = true
}
tags = {
Name = "${var.project}-web-${count.index + 1}"
}
}
# Data source
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
# variables.tf
variable "region" {
description = "AWS region"
type = string
default = "ap-northeast-2"
}
variable "project" {
description = "Project name"
type = string
}
variable "environment" {
description = "Environment (development, staging, production)"
type = string
validation {
condition = contains(["development", "staging", "production"], var.environment)
error_message = "Environment must be development, staging, or production."
}
}
variable "instance_type" {
description = "EC2 instance type"
type = string
default = "t3.micro"
}
variable "instance_count" {
description = "Number of EC2 instances"
type = number
default = 2
}
# environments/prod.tfvars
region = "ap-northeast-2"
project = "myapp"
environment = "production"
instance_type = "t3.medium"
instance_count = 4
# 초기화 - provider 다운로드
terraform init
# 계획 - 변경사항 미리 확인
terraform plan -var-file=environments/prod.tfvars
# 적용 - 실제 인프라 생성/수정
terraform apply -var-file=environments/prod.tfvars
# 상태 확인
terraform state list
terraform state show aws_instance.web[0]
# 특정 리소스만 적용
terraform apply -target=aws_instance.web
# 삭제
terraform destroy -var-file=environments/prod.tfvars
# 포맷팅 및 검증
terraform fmt -recursive
terraform validate
Terraform state 파일에는 비밀번호, 키 등 민감 정보가 평문으로 저장됩니다. S3 암호화, 접근 제한을 필수로 설정하세요.
apply 전에 항상 plan 결과를 확인하세요. 특히 `destroy` 또는 `replace`가 포함된 경우 신중히 검토하세요.
여러 명이 동시에 terraform apply를 실행하면 state가 꼬일 수 있습니다. DynamoDB 등으로 락을 설정하세요.
콘솔에서 수동 변경하면 코드와 실제 상태가 달라집니다. 주기적으로 `terraform plan`으로 drift를 감지하세요.