Terraform data 블록을 통한 데이터 공유

신동수·2024년 3월 19일
0

Terraform

목록 보기
9/10

개요

  • Terraform 을 통해 ec2 라는 폴더안에서 Security Group 리소스를 생성을 해야하는데 vpc_id 값이 필요하여 해당 다른 폴더에 있는 id 값을 참조하는 방법을 알아보기 위해 포스팅을 작성 하였다.

구조

# Terraform tree 구조
.
├── _variables_
│   └── dev
│       ├── common_info.yaml
│       ├── common_tags.yaml
│       └── vpc_info.yaml
├── environments
│   └── dev
│       ├── locals.tf
│       ├── main.tf
│       ├── outputs.tf
│       ├── provider.tf
│       └── variables.tf
└── modules
    ├── ec2
    │   ├── outputs.tf
    │   ├── securitygroup.tf
    │   └── variables.tf
    └── vpc
        ├── igw.tf
        ├── nat.tf
        ├── outputs.tf
        ├── route.tf
        ├── subnet.tf
        ├── variables.tf
        └── vpc.tf

구조는 위와 같으며 moudles/ec2/securitygroup.tf 파일에서 vpc_id 값을 가져오는 방법을 알아보겠다.

# modules/ec2/securitygroup.tf
data "terraform_remote_state" "vpc" {
  backend = "local"

  config = {
    path = "../../environments/dev/terraform.tfstate"
  }
}


resource "aws_security_group" "eks_cluster_sg" {
  name        = "eks-cluster-sg"
  vpc_id = data.terraform_remote_state.vpc.outputs.vpc_id
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "eks-cluster-sg"
  }
}

로컬 상태 파일을 사용하여 데이터값을 공유하려면 다음과 같은 접근 방법을 생각 하였다.
그리고 terraform 초기화를 environments/dev/ 경로에서 진행하기에 tfstate 파일이 해당 경로에 생성이 된다. 그렇기에 path 는 terraform.tfstate 가 존재하는 경로를 지정 하였다.

# modules/vpc/vpc.tf
resource "aws_vpc" "eks_vpc" {
  cidr_block = var.vpc_info.cidr_block_vpc

  tags = merge(
    {
      Name    = "${var.common_info.env}-${var.vpc_info.vpc_name}"
    },
    var.common_tags
  )
}
# modules/vpc/outputs.tf
output "vpc_id" {
  value = aws_vpc.eks_vpc.id
}

결과

# terraform plan
% terraform plan
module.ec2.data.terraform_remote_state.vpc: Reading...
module.ec2.data.terraform_remote_state.vpc: Read complete after 0s
[중략]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # module.ec2.aws_security_group.eks_cluster_sg will be created
  + resource "aws_security_group" "eks_cluster_sg" {
      + arn                    = (known after apply)
      + description            = "Managed by Terraform"
      + egress                 = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = ""
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "-1"
              + security_groups  = []
              + self             = false
              + to_port          = 0
            },
        ]
      + id                     = (known after apply)
      + ingress                = (known after apply)
      + name                   = "eks-cluster-sg"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags                   = {
          + "Name" = "eks-cluster-sg"
        }
      + tags_all               = {
          + "Name" = "eks-cluster-sg"
        }
      + vpc_id                 = "<VPC_ID>"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.%

terraform plan 을 통해 리소스가 생성될 정보를 확인할 수 있었다. 하지만 이러한 접근 방법은 덜 안전하거나 관리하기 어려울 수 있다. 가능하다면, 테라폼 클라우드나 다른 원격 상태 백엔드를 사용하거나, module 호출 시 필요한 값을 가져와 사용하는 방법이 있을 것이다.
아래에서 module 블록에서 필요한 값을 가지고 리소스를 생성하는 과정을 이어가도록 하겠다.

+추가 module 블록을 통한 데이터 공유

# environments/dev/main.tf

module "vpc" {
  source = "../../modules/vpc"

  common_info = local.common_info
  common_tags = local.common_tags
  vpc_info = local.vpc_info
}

module "ec2" {
  source = "../../modules/ec2"

  common_info = local.common_info
  common_tags = local.common_tags
  vpc_id = module.vpc.vpc_id
}
# modules/vpc/outputs.tf

output "vpc_id" {
  value = aws_vpc.eks_vpc.id
}

위 코드처럼 vpc_id 값을 module 에 있는 값을 미리 가져와 사용하는 방법도 있다.

# modules/ec2/securitygroup.tf

resource "aws_security_group" "eks_cluster_sg" {
  name        = "dobby-eks-cluster-sg"
  vpc_id = var.vpc_id
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "dobby-eks-cluster-sg"
  }
}
# modules/ec2/variables.tf

variable "vpc_id" {
  description = "vpc_id"
  type = any
}

위에서 data 블록을 통해 사용하는 것보다 코드가 더 간결해졌다. 테라폼에서는 정답이 없으므로, 상황에 맞는 코드를 작성하여 사용하면 좋을 것 같다.

profile
조금씩 성장하는 DevOps 엔지니어가 되겠습니다. 😄

0개의 댓글

관련 채용 정보