본문 바로가기

IaC

테라폼 스터디 - 7주차 (프로덕션 수준의 인프라 구성)

프로덕션 수준의 인프라 구축이 오래 걸리는 이유

 

 

  • 복잡성
    • 대규모 시스템은 다양한 컴포넌트와 상호작용하기에, 네트워킹, 보안, 스토리지, 가용성, 확장성 등 여러 가지 요소를 고려해야 한다.
    • 각 요소 간의 의존성을 올바르게 설정하고 관리하는 데 시간이 소요된다.
  • 보안 및 규정 준수
    • 프로덕션 환경에서는 데이터 보호와 규정 준수가 필수이기에, 이를 위해 IAM 정책, 데이터 암호화, 네트워크 ACL 등 다양한 보안 설정이 필요하다.
  • 테스트 및 검증
    • 프로덕션 환경에서는 장애가 최소화되어야 하므로, 따라서 모든 변경 사항은 철저히 테스트되어야 하며, 복구 계획이 필요하다.
    • 인프라 코드는 실제 환경에서 배포 전 테스트 환경에서 검증되어야 한다.
  • 자동화 및 지속 가능성
    • 모든 프로세스는 반복 가능하고 자동화되어야 한다. 이를 위해 테라폼 같은 IaC(Infrastructure as Code) 도구를 활용하지만, 초기 설계 및 구현에 시간이 소요된다.
  • 확장성과 가용성 보장
    • 프로덕션 수준 인프라는 높은 트래픽을 처리하고 장애 발생 시에도 복구 가능해야 하므로 고급 설계 및 설정이 필요하다.

 


프로덕션 수준 인프라 체크리스트

  1. 설계 및 계획
    • 요구사항 분석: 확장성, 가용성, 보안 요구사항 정리
    • 아키텍처 다이어그램 작성
    • 사용 서비스와 리소스 정의 (예: VPC, EC2, S3 등)
  2. 테라폼 코드 관리
    • 모듈화된 코드 작성
    • 버전 관리 도입 (예: Git)
    • State 파일 보호 (예: 원격 백엔드 S3와 DynamoDB를 사용한 상태 잠금)
  3. 네트워크 구성
    • VPC, 서브넷, 라우팅 테이블 정의
    • 퍼블릭 및 프라이빗 네트워크 분리
    • 보안 그룹 및 네트워크 ACL 설정
  4. 보안 설정
    • IAM 역할과 정책 정의
    • 데이터 암호화 (예: KMS)
    • 보안 점검 도구 사용 (예: AWS Inspector, TFsec)
  5. 테스트 및 검증
    • 인프라 테스트 자동화 (예: Terratest)
    • QA 환경에서 배포 후 확인
    • 배포 전후의 성능 및 보안 점검
  6. 모니터링 및 로깅
    • CloudWatch 또는 Grafana 설정
    • 로깅 시스템 통합 (예: ELK 스택)
  7. 자동화 및 배포
    • CI/CD 파이프라인 설정
    • 롤백 전략 마련

 


프로덕션 수준 인프라 모듈

3.1 소형 모듈

  • 정의
    소형 모듈은 특정 리소스나 기능을 구현하는 간단한 테라폼 코드 블록 (예: EC2 인스턴스 생성 모듈)
  • 특징
    • 한 가지 작업에 집중
    • 재사용 가능
    • 유지 관리가 용이
  • 예시 - AWS EC2 인스턴스를 생성하는 모듈
module "ec2_instance" {
  source      = "./modules/ec2_instance"
  instance_id = "web-server"
  ami         = "ami-123456"
  instance_type = "t2.micro"
}

 

 


 

3.2 합성 가능한 모듈

  • 정의
    여러 소형 모듈을 조합하여 보다 복잡한 아키텍처를 생성할 수 있는 모듈
  • 특징
    • 상위 수준의 구성을 제공
    • 서로 다른 모듈 간 의존성 관리
  • 예시 - module.network의 출력 값을 입력으로 받아 동작하는 'web_app' 모듈
module "web_app" {
  source     = "./modules/web_app"
  vpc_id     = module.network.vpc_id
  subnets    = module.network.private_subnets
  instances  = ["web1", "web2"]
}

 

 


 

3.3 테스트 가능한 모듈

  • 정의
    테스트 가능한 모듈은 코드를 작성한 후 검증할 수 있는 구조로 설계
  • 특징
    • 입력 변수와 출력 값이 명확
    • Terratest 또는 기타 툴로 테스트 가능
    • 독립적으로 테스트가 가능한 모듈
    • 변경 사항 검증 가능
    • 테스트 자동화 용이
  • 테스트의 예
    • 모듈에서 생성된 리소스가 예상대로 동작하는지 확인
    • 네트워크 설정이 올바른지 검증
# modules/s3_bucket/main.tf
resource "aws_s3_bucket" "example" {
  bucket        = var.bucket_name
  acl           = var.acl
  force_destroy = var.force_destroy
}

resource "aws_s3_bucket_versioning" "example" {
  bucket = aws_s3_bucket.example.id
  versioning_configuration {
    status = var.versioning_enabled ? "Enabled" : "Suspended"
  }
}

output "bucket_name" {
  value = aws_s3_bucket.example.bucket
}

output "bucket_arn" {
  value = aws_s3_bucket.example.arn
}

 

variables.tf

variable "bucket_name" {
  type        = string
  description = "The name of the S3 bucket to create"
}

variable "acl" {
  type        = string
  default     = "private"
  description = "The ACL to apply to the S3 bucket"
}

variable "force_destroy" {
  type        = bool
  default     = false
  description = "Whether to force destroy the bucket (including all objects inside)"
}

variable "versioning_enabled" {
  type        = bool
  default     = true
  description = "Enable versioning for the S3 bucket"
}

 

outputs.tf

output "bucket_name" {
  value = aws_s3_bucket.example.bucket
}

output "bucket_arn" {
  value = aws_s3_bucket.example.arn
}

 

bool 타입 변수들을 통해 모듈의 동작을 검증함


 

3.4 릴리즈 가능한 모듈

  • 정의
    릴리즈 가능한 모듈은 버전 관리 및 태그를 사용하여 안정된 릴리즈를 제공하는 모듈.
  • 특징
    • 태그 기반 배포.
    • 버전 간 변경 사항 기록.
  • 예시
module "vpc" {
  source  = "git::https://github.com/your-repo/terraform-vpc.git?ref=v1.0.0"
}

 


 

3.5 테라폼 모듈 외의 것들

  • 정의
    테라폼 외에 프로덕션 수준 인프라에서 사용되는 추가 도구 및 기법.
  • 예시
    1. CI/CD 도구
      • Jenkins, GitLab CI/CD 등을 사용하여 테라폼 배포 파이프라인 설정.
    2. 테스트 도구
      • Terratest 또는 Checkov를 사용하여 보안 및 성능 테스트 수행
    3. 모니터링 및 로깅
      • Prometheus, EL(F)K 스택을 활용하여 로그 및 모니터링 구축.
    4. 원격 상태 관리
      • S3와 DynamoDB를 사용하여 테라폼 상태 파일 관리

 

Terratest 예시 - go 라이브러리

package test

import (
	"testing"
	"github.com/gruntwork-io/terratest/modules/terraform"
	"github.com/stretchr/testify/assert"
)

func TestS3BucketModule(t *testing.T) {
	t.Parallel()

	terraformOptions := &terraform.Options{
		TerraformDir: "../modules/s3_bucket",
		Vars: map[string]interface{}{
			"bucket_name":       "test-bucket-123",
			"acl":               "private",
			"force_destroy":     true,
			"versioning_enabled": true,
		},
	}

	defer terraform.Destroy(t, terraformOptions)

	terraform.InitAndApply(t, terraformOptions)

	// Verify bucket name output
	bucketName := terraform.Output(t, terraformOptions, "bucket_name")
	assert.Equal(t, "test-bucket-123", bucketName)

	// Verify bucket ARN output is not empty
	bucketArn := terraform.Output(t, terraformOptions, "bucket_arn")
	assert.NotEmpty(t, bucketArn)
}

 

해당 Terratest 사용 예제는 실제 테라폼 인프라 리소스를 생성하고, 출력값을 통해 검증을 하고, 생성한 리소스를 destroy 하는 과정까지 포함되어 있다.

 

테스트 파이프라인 구성을 위해서는 해당 테스트 모듈과 테스트에 적합한 모듈 구성이 필요할 듯 싶다.