IaC(Infrastructure as Code)

Terraform Workspace

cwchoiit 2024. 3. 8. 12:02
728x90
반응형
SMALL
728x90
SMALL

 

Workspace

테라폼에서 Workspace는 프로젝트 단위라고도 생각할 수 있고 상태 관리의 단위라고도 생각할 수 있다. 

예를 들어 환경이 세 가지인(Dev, Staging, Prod) 경우 비슷한 환경에서 살짝 살짝 달라질텐데 이 코드를 복붙해서 세 개의 프로젝트 단위로 관리하기는 비효율적이며 공간 낭비이다. 이럴 때 워크스페이스가 유용하게 사용될 수 있다.

 

이게 가능한 이유는 하나의 테라폼 프로젝트에 여러 Workspace가 만들어질 수 있기 때문이다.

 

현재 프로젝트 트리는 다음과 같다. 아직 Init 조차 하지 않은 상태이다.

다음 main.tf 파일을 보자.

provider "aws" {
  region = "ap-northeast-2"
}

variable "vpc_name" {
  description = "생성되는 VPC의 이름"
  type        = string
  default     = "default"
}

locals {
  common_tags = {
    Project = "Network"
    Owner   = "cwchoiit"
  }
}

output "vpc_name" {
  value = module.vpc.name
}

output "vpc_id" {
  value = module.vpc.id
}

output "vpc_cidr" {
  description = "생성된 VPC의 CIDR 영역"
  value = module.vpc.cidr_block
}

output "subnet_groups" {
  value = {
    public  = module.subnet_group__public
    private = module.subnet_group__private
  }
}

module "vpc" {
  source  = "tedilabs/network/aws//modules/vpc"
  version = "0.24.0"

  name                  = var.vpc_name
  cidr_block            = "10.0.0.0/16"

  internet_gateway_enabled = true

  dns_hostnames_enabled = true
  dns_support_enabled   = true

  tags = local.common_tags
}

module "subnet_group__public" {
  source  = "tedilabs/network/aws//modules/subnet-group"
  version = "0.24.0"

  name                    = "${module.vpc.name}-public"
  vpc_id                  = module.vpc.id
  map_public_ip_on_launch = true

  subnets = {
    "${module.vpc.name}-public-001/az1" = {
      cidr_block           = "10.0.0.0/24"
      availability_zone_id = "apne2-az1"
    }
    "${module.vpc.name}-public-002/az2" = {
      cidr_block           = "10.0.1.0/24"
      availability_zone_id = "apne2-az2"
    }
  }

  tags = local.common_tags
}

module "subnet_group__private" {
  source  = "tedilabs/network/aws//modules/subnet-group"
  version = "0.24.0"

  name                    = "${module.vpc.name}-private"
  vpc_id                  = module.vpc.id
  map_public_ip_on_launch = false

  subnets = {
    "${module.vpc.name}-private-001/az1" = {
      cidr_block           = "10.0.10.0/24"
      availability_zone_id = "apne2-az1"
    }
    "${module.vpc.name}-private-002/az2" = {
      cidr_block           = "10.0.11.0/24"
      availability_zone_id = "apne2-az2"
    }
  }

  tags = local.common_tags
}

 

 

Workspace commands

workspace 관련해서 Commands가 존재하는데 다음 help 명령어를 보자.

 

list

list는 현재 디렉토리에서 존재하는 workspace들의 리스트를 보여준다. 현 시점에서 해당 커맨드를 입력해보면,

다른 workspace를 만든적이 없으면 기본으로 'default' 하나를 가지고 있다.

 

show

show는 현재 선택된 workspace가 무엇인지 보여준다. 당연히 현재는 workspace를 만든적도 없으니 'default'가 선택된 상태다.

근데 이거 굳이 안 써도 되는게 list 명령어를 사용하면 별표 표시로 현재 선택된 workspace를 알려준다.

 

new

workspace를 새로 만드는 명령어. 다음과 같이 사용해보자.

 

workspace가 만들어졌고 만듦과 동시에 해당 workspace로 현재 workspace가 변경된다.

그리고 workspace가 둘 이상 생기게 되면 그 동시에 해당 프로젝트에 다음과 같은 폴더가 하나 생긴다.

workspace 별 관리하는 상태가 다 다를테니 당연히 각 workspace 마다 상태 관리 파일이 나뉘어지게 되는것이다.

 

select

workspace를 선택하는 명령어. 다음과 같이 사용하면 된다.

 

delete

workspace를 삭제하는 명령어. 다음과 같이 사용하면 된다.

 

삭제하면 terraform.tfstate.d 폴더 내 해당 workspace 폴더도 삭제된다.

 

 

Workspace Use Case

이제 workspace를 쓸만한 방식으로 한번 구성해보자. 환경이 세 가지가 있다고 가정하자.

그러면 workspace 3개가 필요하다. 3개의 workspace를 일단 만들자.

  • dev
  • prod
  • staging

이 각각의 환경은 구성이 다를 것이다. 비슷한 코드의. 

그렇기에 하나의 main.tf 파일로 관리하고 각 환경마다 변경되는 부분만 다르게 변수로 받아 관리하면 더 효율적일 수 있다.

그래서 나는 다음과 같은 세 개의 파일을 만들었다.

  • dev.tfvars
  • prod.tfvars
  • staging.tfvars

그리고 각각의 파일에 이러한 내용을 추가했다.

 

dev.tfvars

vpc_name = "dev"

 

prod.tfvars

vpc_name = "prod"

 

staging.tfvars

vpc_name = "staging"

 

 

그리고 나의 main.tf 파일은 다음과 같다.

provider "aws" {
  region = "ap-northeast-2"
}

variable "vpc_name" {
  description = "생성되는 VPC의 이름"
  type        = string
}

locals {
  common_tags = {
    Project = "Network"
    Owner   = "cwchoiit"
  }
}

output "vpc_name" {
  value = module.vpc.name
}

output "vpc_id" {
  value = module.vpc.id
}

output "vpc_cidr" {
  description = "생성된 VPC의 CIDR 영역"
  value = module.vpc.cidr_block
}

output "subnet_groups" {
  value = {
    public  = module.subnet_group__public
    private = module.subnet_group__private
  }
}

module "vpc" {
  source  = "tedilabs/network/aws//modules/vpc"
  version = "0.24.0"

  name                  = var.vpc_name
  cidr_block            = "10.0.0.0/16"

  internet_gateway_enabled = true

  dns_hostnames_enabled = true
  dns_support_enabled   = true

  tags = local.common_tags
}

module "subnet_group__public" {
  source  = "tedilabs/network/aws//modules/subnet-group"
  version = "0.24.0"

  name                    = "${module.vpc.name}-public"
  vpc_id                  = module.vpc.id
  map_public_ip_on_launch = true

  subnets = {
    "${module.vpc.name}-public-001/az1" = {
      cidr_block           = "10.0.0.0/24"
      availability_zone_id = "apne2-az1"
    }
    "${module.vpc.name}-public-002/az2" = {
      cidr_block           = "10.0.1.0/24"
      availability_zone_id = "apne2-az2"
    }
  }

  tags = local.common_tags
}

module "subnet_group__private" {
  source  = "tedilabs/network/aws//modules/subnet-group"
  version = "0.24.0"

  name                    = "${module.vpc.name}-private"
  vpc_id                  = module.vpc.id
  map_public_ip_on_launch = false

  subnets = {
    "${module.vpc.name}-private-001/az1" = {
      cidr_block           = "10.0.10.0/24"
      availability_zone_id = "apne2-az1"
    }
    "${module.vpc.name}-private-002/az2" = {
      cidr_block           = "10.0.11.0/24"
      availability_zone_id = "apne2-az2"
    }
  }

  tags = local.common_tags
}

 

 

Dev Workspace

이제 workspace 중 dev로 변경하고 apply를 진행해보자.

tf workspace select dev
tf apply -var-file=dev.tfvars

 

성공적으로 수행된 후 AWS Console에 가서 확인해보자.

dev 관련 네트워크가 잘 만들어졌음을 확인할 수 있다.

 

Staging Workspace

마찬가지로 staging workspace로 가서 같은 작업을 수행해보자.

tf workspace select staging
tf apply -var-file=staging.tfvars

 

Prod Workspace

tf workspace select staging
tf apply -var-file=staging.tfvars

 

결론

이렇게 각 Workspace별로 네트워크 구성에 대해 작업해 보았다. 이런식으로 같은 main.tf 파일을 사용하면서 환경에 맞게 변수 파일을 다르게 등록해서 workspace 별 작업이 가능하다. 

728x90
반응형
LIST

'IaC(Infrastructure as Code)' 카테고리의 다른 글

Terraform 나만의 Module 만들어보기  (0) 2024.03.10
Terraform Cloud  (0) 2024.03.10
Terraform Commands (taint / untaint)  (0) 2024.03.08
Terraform State  (0) 2024.03.07
AWS + Terraform (Loop)  (0) 2024.03.07