# Terraform 면접 질문 완벽 가이드 2026: Infrastructure as Code 핵심 정리 > Terraform 면접에서 자주 출제되는 상태 관리, 모듈, 워크스페이스, 프로바이더, IaC 모범 사례를 체계적으로 정리합니다. 2026년 Terraform 1.14 및 HCP Terraform 최신 내용을 반영하였습니다. - Published: 2026-04-14 - Updated: 2026-04-14 - Author: SharpSkill - Tags: terraform, infrastructure-as-code, devops, iac, interview - Reading time: 10 min --- Terraform 면접 질문은 후보자가 클라우드 인프라를 선언적으로 관리하고, 상태(state)를 안전하게 다루며, 재사용 가능한 모듈을 설계하는 능력을 평가합니다. Terraform 1.14에서 모듈 소스에 변수를 사용할 수 있게 되었고 HCP Terraform이 관리형 실행 플랫폼을 확장함에 따라, 2026년 면접관은 후보자에게 기본적인 HCL 지식뿐만 아니라 진화하는 IaC 생태계에 대한 이해도까지 기대합니다. > **면접관이 실제로 평가하는 포인트** > > Terraform 면접에서 문법 암기를 중시하는 경우는 드뭅니다. 핵심 평가 영역은 상태 관리 전략, 모듈 설계 패턴, 시크릿 처리, 그리고 운영 환경에서의 plan/apply 사이클에 대한 추론 능력입니다. ## 모든 후보자가 알아야 할 Terraform 핵심 개념 ### Terraform이란 무엇이며 다른 IaC 도구와 어떻게 다릅니까? Terraform은 HCL(HashiCorp Configuration Language)로 작성된 구성 파일을 통해 클라우드 리소스를 관리하는 선언적 Infrastructure as Code 도구입니다. Ansible이나 셸 스크립트와 같은 명령형(imperative) 도구와 달리, Terraform은 현재 인프라를 추적하는 상태 파일을 유지하고 변경 사항을 적용하기 전에 차이점("plan")을 계산합니다. 핵심 차별점은 다음과 같습니다. Terraform은 클라우드 비종속적(AWS, Azure, GCP 및 수백 개의 프로바이더를 지원)이며, 예기치 않은 변경을 방지하는 plan-before-apply 워크플로를 사용하고, 내부 방향성 비순환 그래프(DAG)를 통해 리소스 종속성을 관리합니다. 탄탄한 답변에는 생태계 변화에 대한 언급도 포함되어야 합니다. HashiCorp가 2023년에 BSL 라이선스를 채택한 이후, Linux Foundation 산하에서 오픈소스 포크인 OpenTofu가 등장하였습니다. 두 도구는 동일한 HCL 구문을 공유하지만 기능 면에서 분화되고 있습니다. Terraform 1.14는 HCP와의 플랫폼 통합에 중점을 두고, OpenTofu 1.9는 상태 암호화 및 동적 백엔드를 우선시합니다. ### Terraform 워크플로 설명: init, plan, apply, destroy 네 가지 핵심 명령어는 모든 Terraform 작업의 수명 주기를 구성합니다. ```bash # 1. Initialize - 프로바이더와 모듈 다운로드 terraform init # 2. Plan - 아무것도 수정하지 않고 변경될 내용 표시 terraform plan -out=tfplan # 3. Apply - 계획된 변경 사항 실행 terraform apply tfplan # 4. Destroy - 관리 중인 모든 리소스 삭제 terraform destroy ``` `terraform init`은 프로바이더 플러그인을 다운로드하고 백엔드를 초기화합니다. `terraform plan`은 원하는 상태(구성 파일)와 실제 상태(상태 파일)를 비교하여 변경 세트를 출력합니다. `terraform apply`는 해당 변경 세트를 실행합니다. `-out` 옵션으로 plan을 파일에 저장하면 검토된 정확한 plan이 적용되도록 보장할 수 있으며, 이는 CI/CD 파이프라인에서 필수적입니다. ## 상태 관리: 가장 자주 출제되는 면접 주제 ### Terraform 상태란 무엇이며 왜 중요합니까? Terraform 상태는 구성 리소스를 실제 인프라 객체에 매핑하는 JSON 파일(`terraform.tfstate`)입니다. 상태 없이는 Terraform이 무엇이 존재하는지, 무엇이 변경되었는지, 무엇을 삭제해야 하는지 판단할 수 없습니다. 상태에는 리소스 ID, 속성 값, 종속성 메타데이터가 포함됩니다. 상태를 잃으면 Terraform이 관리하는 모든 리소스를 추적할 수 없게 되며, 모든 객체를 수동으로 import하거나, 더 심한 경우 비용이 계속 발생하는 고아 클라우드 리소스가 남게 됩니다. ### 운영 환경에서 상태를 어떻게 관리해야 합니까? 로컬 상태 파일은 팀 환경에서 사용할 수 없습니다. 표준 운영 환경 설정은 잠금(locking) 기능이 있는 원격 백엔드를 사용합니다. ```hcl # backend.tf terraform { backend "s3" { bucket = "company-terraform-state" key = "prod/networking/terraform.tfstate" region = "eu-west-1" dynamodb_table = "terraform-locks" encrypt = true } } ``` 이 구성은 서버 측 암호화를 적용하여 S3에 상태를 저장하고, DynamoDB를 사용하여 상태 잠금을 수행합니다. 잠금은 두 명의 엔지니어(또는 두 개의 CI 파이프라인)가 동시에 `apply`를 실행하여 상태를 손상시키는 것을 방지합니다. HCP Terraform(이전 명칭 Terraform Cloud)은 추가 인프라 없이 상태 저장, 잠금, 실행 이력, RBAC를 처리하는 관리형 대안을 제공합니다. HashiCorp 생태계에 이미 투자한 조직의 경우, S3 버킷과 DynamoDB 테이블을 유지 관리하는 오버헤드를 없앨 수 있습니다. ### 상태 파일 모범 사례는 무엇입니까? - `terraform.tfstate`를 절대로 버전 관리에 커밋하지 않아야 합니다. 데이터베이스 비밀번호, API 키 등의 시크릿이 평문으로 포함될 수 있습니다. - 백엔드에서 저장 시 암호화를 활성화합니다(S3 SSE, GCS 암호화, Azure Storage 암호화). - 환경별로 별도의 상태 파일을 사용합니다. dev, staging, production에 단일 상태 파일을 사용하는 것은 우발적 파괴의 원인이 됩니다. - 상태 잠금을 구현합니다. 잠금을 지원하는 모든 원격 백엔드에서 잠금을 활성화해야 합니다. - `terraform state list`와 `terraform state show`를 실행하여 상태를 수정하지 않고 검사할 수 있습니다. > **상태 파일 재해 복구** > > 상태 백엔드에서 항상 버전 관리를 활성화해야 합니다(S3 버전 관리, GCS 객체 버전 관리). 백업 없이 상태 파일이 손상되거나 실수로 삭제되면 복구를 위해 수 시간의 수동 `terraform import` 작업이 필요할 수 있습니다. ## 모듈: 재사용 가능한 인프라 컴포넌트 ### Terraform 모듈은 어떻게 작동합니까? 모듈은 리소스 집합을 캡슐화하는 `.tf` 파일이 포함된 디렉터리입니다. 모든 Terraform 구성은 기술적으로 모듈(루트 모듈)입니다. 자식 모듈은 재사용을 촉진하고 표준을 강제하기 위해 루트 모듈에서 호출됩니다. ```hcl # main.tf - 모듈 호출 module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "5.16.0" name = "production-vpc" cidr = "10.0.0.0/16" azs = ["eu-west-1a", "eu-west-1b", "eu-west-1c"] private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] enable_nat_gateway = true single_nat_gateway = true } ``` Terraform 1.14는 중요한 개선 사항을 도입하였습니다. 이제 모듈 `source`와 `version` 속성에 변수(variables)와 locals를 사용할 수 있습니다. 이전에는 동적 모듈 소싱을 위해 Terragrunt와 같은 우회 방법을 강제하던 고정적인 제한 사항이었습니다. ### 잘 설계된 모듈의 조건은 무엇입니까? 운영 수준의 모듈은 다음 원칙을 따릅니다. - **명확한 입출력**: 모든 변수에 설명, 타입 제약 조건, 적용 가능한 경우 합리적인 기본값이 있어야 합니다. 출력(outputs)은 하류 모듈이 필요로 하는 값을 노출합니다. - **최소 범위**: 모듈은 하나의 논리적 컴포넌트(VPC, 데이터베이스 클러스터, Kubernetes 네임스페이스)를 관리하며, 전체 환경을 관리하지 않습니다. - **하드코딩 금지**: 프로바이더 구성, 리전, 계정 ID, 환경별 값은 변수를 통해 전달되며, 모듈 내부에서 리터럴로 작성하지 않습니다. - **버전 관리된 릴리스**: 게시된 모듈은 시맨틱 버전 관리를 사용합니다. `version = "5.16.0"`을 고정하면 예기치 않은 주요 변경 사항을 방지할 수 있습니다. ## 워크스페이스, 환경, 프로젝트 구조 ### 다중 환경을 어떻게 관리해야 합니까? 세 가지 일반적인 패턴이 존재하며, 각각 뚜렷한 트레이드오프가 있습니다. | 패턴 | 메커니즘 | 적합한 경우 | 위험 요소 | |------|----------|-------------|----------| | 워크스페이스 | `terraform workspace select prod` | 단순한 프로젝트, 환경별 동일 구성 | 공유 상태 백엔드, 잘못된 워크스페이스에 `apply` 실행 가능 | | 디렉터리별 환경 | 별도의 `dev/`, `staging/`, `prod/` 디렉터리 | 환경 간 완전한 격리 | 디렉터리 간 코드 중복 | | Terragrunt | 백엔드 구성을 생성하는 DRY 래퍼 | 대규모 멀티 계정 환경 | 추가 도구 의존성 | 공유 모듈을 사용한 디렉터리별 환경 접근 방식이 운영 환경에서 가장 일반적입니다. 각 환경 디렉터리에는 동일한 모듈을 다른 변수 값으로 호출하는 `main.tf`가 포함되어 있으며, 각각 자체적으로 격리된 상태 파일을 보유합니다. ### `terraform workspace`와 디렉터리 격리의 차이점은 무엇입니까? 워크스페이스는 동일한 백엔드 내에서 이름이 지정된 상태 파일을 생성합니다. `terraform workspace select staging`으로 워크스페이스를 전환하면 Terraform이 읽고 쓰는 상태 파일이 변경되지만, 구성 자체는 동일하게 유지됩니다. 제한 사항은 다음과 같습니다. 워크스페이스는 동일한 백엔드 구성과 프로바이더 설정을 공유합니다. 디렉터리 격리는 더 강력한 경계를 제공하며, 각 환경이 다른 AWS 계정, 다른 상태 백엔드, 또는 다른 프로바이더 버전을 사용할 수 있습니다. 엄격한 폭발 반경 제어가 필요한 규제 환경에서는 디렉터리 격리가 더 안전한 선택입니다. ## 프로바이더, 데이터 소스, 리소스 수명 주기 ### 프로바이더란 무엇이며 어떻게 구성합니까? 프로바이더는 HCL 구성을 특정 플랫폼에 대한 API 호출로 변환하는 플러그인입니다. AWS 프로바이더는 AWS API를 호출하고, Kubernetes 프로바이더는 Kubernetes API 서버와 통신합니다. ```hcl # providers.tf terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.80" } } } provider "aws" { region = var.aws_region default_tags { tags = { Environment = var.environment ManagedBy = "terraform" Team = var.team_name } } } ``` `~> 5.80` 버전 제약 조건은 패치 업데이트(5.80.x)를 허용하지만 마이너 버전 변경은 차단하여, 안정성과 보안 패치 사이의 균형을 유지합니다. `default_tags` 블록은 프로바이더가 생성하는 모든 리소스에 일관된 태깅을 적용하며, 이는 거버넌스 및 비용 할당에 대한 일반적인 면접 논의 포인트입니다. ### 데이터 소스와 리소스의 차이점을 설명하십시오 리소스(`resource` 블록)는 인프라를 생성, 업데이트, 삭제합니다. 데이터 소스(`data` 블록)는 기존 인프라를 관리하지 않고 읽기만 합니다. ```hcl # 데이터 소스 - 기존 AMI를 읽으며, 아무것도 생성하지 않음 data "aws_ami" "ubuntu" { most_recent = true owners = ["099720109477"] # Canonical filter { name = "name" values = ["ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*"] } } # 리소스 - 데이터 소스를 사용하여 EC2 인스턴스 생성 resource "aws_instance" "web" { ami = data.aws_ami.ubuntu.id instance_type = "t3.micro" } ``` 데이터 소스는 `plan` 중에 평가되므로, 공유 인프라 참조(다른 팀이 생성한 VPC), 동적 값 조회(최신 AMI ID), 외부 구성 읽기(SSM 파라미터, Vault 시크릿)에 유용합니다. > **수명 주기 메타 인수** > > 면접에서 자주 등장하는 세 가지 수명 주기 규칙은 다음과 같습니다. `create_before_destroy`(무중단 교체), `prevent_destroy`(데이터베이스와 같은 중요 리소스 보호), `ignore_changes`(ASG desired capacity와 같이 Terraform 외부에서 수정되는 필드에 대한 드리프트 방지). ## 고급 주제: Import, Moved 블록, 테스팅 ### `terraform import`는 어떻게 작동하며 언제 필요합니까? `terraform import`는 기존 클라우드 리소스를 Terraform 리소스 블록에 연결합니다. 일반적인 시나리오는 인프라가 수동으로(ClickOps) 또는 다른 도구로 생성되었고, 팀이 이제 Terraform으로 관리하려는 경우입니다. Terraform 1.5 이상에서는 CLI 전용 워크플로를 대체하는 `import` 블록을 구성에 직접 도입하였습니다. ```hcl # import.tf import { to = aws_s3_bucket.legacy_data id = "my-legacy-bucket-name" } resource "aws_s3_bucket" "legacy_data" { bucket = "my-legacy-bucket-name" } ``` 이 블록과 함께 `terraform plan`을 실행하면 기존 버킷을 상태로 수용하는 plan이 생성됩니다. 이 선언적 import 접근 방식은 풀 리퀘스트에서 검토 가능하고, 반복 가능하며, 상태에 대한 직접적인 CLI 액세스가 필요하지 않습니다. ### `moved` 블록이란 무엇입니까? Terraform 코드를 리팩터링(리소스 이름 변경, 모듈로 이동)할 때 과거에는 `terraform state mv` 명령이 필요하였습니다. `moved` 블록은 이를 선언적으로 처리합니다. ```hcl # 리소스 이름을 "web"에서 "app"으로 변경 moved { from = aws_instance.web to = aws_instance.app } ``` Terraform은 plan 중에 이동을 인식하고 상태를 자동으로 업데이트하여, 삭제 후 재생성 사이클을 방지합니다. 이는 대규모 구성을 모듈로 재구조화할 때 매우 유용합니다. ### Terraform 테스팅은 어떻게 작동합니까? Terraform 1.6 이상에는 `.tftest.hcl` 파일을 사용하는 네이티브 테스팅 프레임워크가 포함되어 있습니다. ```hcl # tests/vpc.tftest.hcl run "creates_vpc_with_correct_cidr" { command = plan assert { condition = aws_vpc.main.cidr_block == "10.0.0.0/16" error_message = "VPC CIDR block does not match expected value" } } run "creates_three_private_subnets" { command = plan assert { condition = length(aws_subnet.private) == 3 error_message = "Expected 3 private subnets" } } ``` Terraform 1.14에서는 함수를 허용하는 mock 블록, 실패한 테스트 디버깅을 위한 `skip_cleanup`, run 블록 내의 격리된 테스트 상태를 위한 backend 블록 등으로 기능이 확장되었습니다. 네이티브 테스팅은 기본적인 검증을 위해 Terratest와 같은 외부 도구의 필요성을 없애줍니다. ## CI/CD 파이프라인에서의 Terraform ### 운영 환경 Terraform 파이프라인은 어떤 모습입니까? 견고한 CI/CD 파이프라인은 모든 단계에서 안전을 강제합니다. 1. **린트 및 검증**: `terraform fmt -check`와 `terraform validate`로 구문 문제를 감지합니다. 2. **PR 시 Plan**: 모든 풀 리퀘스트에서 `terraform plan`을 실행하고 출력을 PR 코멘트로 게시합니다. 검토된 plan 없이는 apply를 수행하지 않습니다. 3. **정책 검사**: OPA(Open Policy Agent), Sentinel(HCP Terraform), Checkov 등의 도구로 조직 정책(퍼블릭 S3 버킷 금지, 필수 암호화, 필수 태그)에 대해 plan을 검증합니다. 4. **머지 시 Apply**: PR 승인 및 정책 검사 통과 후, 저장된 plan 파일에서 `terraform apply`가 자동으로 실행됩니다. 5. **상태 백업**: apply 후 파이프라인이 상태 무결성을 검증하고, 백엔드의 버전 관리가 새로운 상태 버전을 캡처합니다. 황금률: 어떤 사람도 로컬 머신에서 운영 환경에 대해 `terraform apply`를 실행해서는 안 됩니다. 모든 운영 환경 apply는 파이프라인을 통해 수행되어야 합니다. ## 결론 Terraform 면접 준비의 핵심 요약은 다음과 같습니다. - 상태 관리는 가장 중요한 단일 주제입니다. 면접에 들어가기 전에 원격 백엔드, 잠금, 암호화, 재해 복구 전략을 반드시 이해해야 합니다. - 모듈 설계는 주니어와 시니어 후보자를 구분합니다. 명확한 인터페이스와 최소 범위를 가진 재사용 가능하고 버전 관리된 모듈을 구축하는 능력을 보여주어야 합니다. - plan/apply 워크플로를 깊이 이해해야 합니다. plan을 파일로 저장하는 것이 왜 중요한지, DAG가 실행 순서를 어떻게 결정하는지, `-target`이 무엇을 하는지(그리고 왜 아껴서 사용해야 하는지) 설명할 수 있어야 합니다. - Terraform 1.14는 모듈 소스에서의 변수 사용, 확장된 테스팅, 더 긴밀한 HCP 통합을 제공합니다. 최신 기능을 언급하면 생태계에 대한 적극적인 관심을 보여줄 수 있습니다. - Terraform 대 OpenTofu 현황을 솔직하게 다루어야 합니다. 라이선스 분리, 기능 분화, 각 도구의 적합한 사용 시나리오를 이해하면 구문 지식을 넘어선 아키텍처적 성숙도를 보여줄 수 있습니다. - Terraform 세부 사항과 함께 [DevOps 면접 기초](/blog/devops/essential-devops-interview-questions)를 학습하는 것이 좋습니다. 면접관은 IaC 질문과 더 넓은 인프라 주제를 자주 혼합하여 출제합니다. - Terraform이 Kubernetes 워크로드가 실행되는 클러스터를 프로비저닝하는 경우가 많으므로, [Kubernetes 배포 개념](/blog/devops/kubernetes-deploying-first-application)도 함께 복습하는 것이 좋습니다. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/ko/blog/devops/terraform-interview-questions-infrastructure-as-code