IaC(Infrastructure as Code)

terraform_remote_state

cwchoiit 2024. 3. 10. 20:22
728x90
반응형
SMALL
728x90
SMALL

 

terraform_remote_state는 어떤것이고 어떻게 활용하는지 알아보자.

terraform_remote_state

이 terraform_remote_state는 Data Source로써 사용이 가능하다. hasicorp에서 공식적으로 지원하는 Terraform 이라는 Provider를 사용하면 이를 구현할 수 있다.

 

The terraform_remote_state Data Source | Terraform | HashiCorp Developer

Retrieves the root module output values from a Terraform state snapshot stored in a remote backend.

developer.hashicorp.com

 

예전에는 Terraform Registry에 Provider에 Terraform이 있었는데 지금은 위 문서로 대체된듯하다. 여튼 위 문서를 참조하면 된다.

 

이 terraform_remote_state의 핵심은 각 워크스페이스 별 상태관리 파일이 있음을 이제 알고 있다. .tfstate 파일로 된. 이 파일을 참조해서 다른 워크스페이스에서 이 상태를 가져다가 사용하겠다는 것이 terraform_remote_state의 핵심이다.

 

근데 이 때 Backend가 무엇이냐에(local, remote) 따라 작성 방식이 살짝 다르다. 이 내용도 위 문서에 있다.

 

The terraform_remote_state Data Source | Terraform | HashiCorp Developer

Retrieves the root module output values from a Terraform state snapshot stored in a remote backend.

developer.hashicorp.com

 

 

The terraform_remote_state Data Source | Terraform | HashiCorp Developer

Retrieves the root module output values from a Terraform state snapshot stored in a remote backend.

developer.hashicorp.com

 

그럼 이제 코드 구조를 한번 살펴보자. 구조는 다음과 같다.

 

설명을 하자면 network 라는 워크스페이스가 만들어내는 리소스가 .tfstate 파일에 저장되어 그 파일을 바라보고 ec2 워크스페이스가 사용할 것이다.

 

network/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
}

이 파일은 기존에 계속 사용했던 network 테라폼 소스이다.

 

network/terraform.tfvars

vpc_name = "remote-state"

 

이렇게 두 개의 파일을 가지는 network 워크스페이스를 Apply 해보자. 정상적으로 수행이 잘 됐다.

 

그럼 이제 주의깊게 봐야하는 파일이 이 Apply를 하고 난 후 생성되는 .tfstate 파일이다.

 

이 파일을 바라보게 EC2 워크스페이스가 작업이 될 것이다.

 

ec2/main.tf

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

data "terraform_remote_state" "network" {
  backend = "local"

  config = {
    path = "${path.module}/../network/terraform.tfstate"
  }
}

locals {
  vpc_name      = data.terraform_remote_state.network.outputs.vpc_name
  subnet_groups = data.terraform_remote_state.network.outputs.subnet_groups
}

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"] # Canonical
}

resource "aws_instance" "terraform-ec2" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"
  subnet_id     = local.subnet_groups["public"].ids[0]

  tags = {
    Name = "${local.vpc_name}-ubuntu"
  }
}

 

여기서 주의깊게 볼 부분은 이 부분이다.

data "terraform_remote_state" "network" {
  backend = "local"

  config = {
    path = "${path.module}/../network/terraform.tfstate"
  }
}

locals {
  vpc_name      = data.terraform_remote_state.network.outputs.vpc_name
  subnet_groups = data.terraform_remote_state.network.outputs.subnet_groups
}

우선, terraform_remote_state를 Data Source로 사용한다. backend는 Local이고 그 경로는 이 파일의 상위 경로에 있는 network 워크스페이스의 .tfstate 파일이 된다.

그리고 로컬 변수로 vpc_name과 subnet_groups를 만들어주는데 이 각각의 변수값을 위에서 선언한 terraform_remote_state의 DataSource를 사용한다. 다만 여기서 한가지 주의할 점은 remote_state를 가져올 땐 .outputs 을 통해서 가져와야한다.

data.terraform_remote_state.network.outputs.vpc_name 이런식으로 말이다.

 

그리고 이 로컬 변수를 EC2 리소스에서도 사용한다. 하단 소스를 보면 subnet_id와 tags의 Name을 로컬변수를 가지고 사용했다.

resource "aws_instance" "terraform-ec2" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"
  subnet_id     = local.subnet_groups["public"].ids[0]

  tags = {
    Name = "${local.vpc_name}-ubuntu"
  }
}

 

이 EC2 워크스페이스를 Apply해보자. 다음과 같이 정상적으로 끝난다.

 

이제 AWS Console에서 확인해보자. 우선 VPC, Subnets을 먼저 확인해보자.

 

만든 remote-state가 prefix로 붙은 VPC와 Subnets이 잘 만들어졌고 이 state를 사용한 EC2가 다음과 같이 잘 만들어졌다.

 

 

결론

이렇게 terraform_remote_state를 활용해서 다른 워크스페이스의 state를 가져와 참조하는 기능을 사용해보았다.

728x90
반응형
LIST

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

Packer Part. 1  (0) 2024.03.14
Terraform Provisioner/EC2 Userdata  (2) 2024.03.11
Terraform 나만의 Module 만들어보기  (0) 2024.03.10
Terraform Cloud  (0) 2024.03.10
Terraform Workspace  (0) 2024.03.08