클라우드/AWS-Terraform

terraform 배포 전략

Hoony.Song 2023. 10. 23. 20:27
반응형
회사 프로젝트에서 terraform을 도입 하여 인프라스트럭처를 코드로 관리 하고 있습니다
terraform으로 서로 다른 배포환경(dev,test,prod)의 인프라를 관리 하는 방법에 대해 서술 합니다

 

Project 단위 분리

  • 프로젝트 분리를 통한 배포환경 분리 방법
  • terraform 으로 서로 다른 배포환경의 인프라를 관리 하는 가장 단순한 방법은 프로젝트를 환경별로 분리 하는 방법 입니다
┬terraform_dev 
├── main
│   ├── main.tf
│   └── provider.tf
└modules

┬terraform_prod 
├── main
│   ├── main.tf
│   └── provider.tf
└modules
  • 서로 다른 프로젝트이기 때문에 credentials, backend 등의 config 를 포함해 모든 리소스를 완벽하게 격리할 수 있지만, 거의 동일한 코드를 복사-붙여넣기 해야해서 중복 코드가 늘어나 유지보수가 어렵기 때문에 좋은 방법은 아닙니다

 

Directory 분리

  • directory 분리를 통한 배포환경 분리 방법
  • 모듈을 공통으로 쓰고 provision을 directory로 나눠 관리 하는 방법 입니다
┬main 
│└ provision
│  ├ dev
│  │ ├── main.tf
│  │ ├── variables.tf
│  │ ├── outputs.tf
│  │ └── provider.tf
│  └ prod
│    ├── ....
└modules
  • terraform init 과 terraform apply를 각각 main/provision/dev 와 main/provision/prod에서 실행 하여 각각의 main.tf를 동작 시키는 방법 입니다
  • 하나의 프로젝트기 때문에 config 설정을 공유 하여 유지보수를 좀 더 쉽게 할 수 있습니다 하지만 여전히 프로젝트 분리만큼은 아니지만 어느정도 중복 코드가 발생 할 수 있습니다

 

Workspace 분리

Workspace를 사용한 배포환경 분리 방법

  • Terraform에서는 Workspace라는 기능을 제공 합니다
  • Workspace는 Terraform state 격리한 작업공간을 제공하여 하나의 코드베이스만으로 여러 배포환경을 구성 · 관리 할 수 있습니다
  • 개발 환경에 따라 Workspace를 만들고 선택 해 배포 합니다
# Create a new workspace
terraform workspace new prod
# Select a workspace (already created)
terraform workspace select prod
# Plan or Apply
terraform plan
terraform apply

 

Provisioning Code 분리

원래의 main provisioning 의 구성은
하나의 폴더 안에서 모든 모듈을 한번에 생성하고 삭제 했습니다
VPC/EC2 와 같은 기본적인 인프라만 프로비저닝 할거라면 상관 없지만
compute , database , dns , instance 등 다양한 서비스들을 한번에 구성 하는것은 바람직 하지 못하다 생각 됩니다
한번 생성 되면 크게 바뀔 일이 없는 기본적인 컴포넌트들과 탄력적ip 같이 바뀌면 곤란한 컴포넌트들을 위해 terraform의 provisioning Code는 환경이나 카테고리별로 실행 환경을 분리 하는것이 맞다고 생각 합니다

 

  • 기존의 일괄 provisioning 구성
┬main 
│└ provision
│  ├ dev                    # terraform apply
│  │ ├── init_resource.tf   # vpc security_group 
│  │ ├── init_instance.tf   # ec2(gitlab , nexus , bastion) , eks 
│  │ ├── init_iam.tf        # iam 
│  │ ├── init_rds.tf        # postgres 
│  └ prod
└modules

 

  • 분리 된 provisioning 구성
main
├─ provision
│  ├─ dev
│  │  ├─ compute        # terraform apply 
│  │  │  └─ main.tf         # vpc security_group
│  │  ├─ instance       # terraform apply
│  │  │  └─ main.tf         # ec2(gitlab , nexus , bastion) , eks
│  │  ├─ database       # terraform apply
│  │  │  └─ main.tf         # postgres
│  │  └─ Network        # terraform apply
│  │     └─ main.tf         # alb , route53 
│  └ prod
└modules

 

  • compute instance 에서 따로 terraform apply 를 하게 되면 각각 다른 .tfstate file을 가집니다
  • tfstate안에 outputs 항목에서 module의 output으로 내보냈던 vpc_id 등 변수들을 가져 올 수 있습니다

 

  • .tfstate 파일이 local 일 때
    • # ../instance.tf 
      
      data "terraform_remote_state" "vpc" {
        backend = "local"
        config = {
          path = "../compute/terraform.tfstate"
        }
      }
      
      vpc_id = data.terraform_remote_state.vpc.outputs.vpc_id 

 

 

  • .tfstate 파일이 s3 일 때
    • # ../instance.tf
      
      data "terraform_remote_state" "vpc" {
        backend = "s3"
        config = {
          bucket  = "<bucket-name>"
          key     = "compute/terraform.tfstate"
          region  = "ap-northeast-2"
        }
      }
      vpc_id = data.terraform_remote_state.vpc.outputs.vpc_id

 

반응형