# 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 블록에서 필요한 값을 가지고 리소스를 생성하는 과정을 이어가도록 하겠다.
# 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 블록을 통해 사용하는 것보다 코드가 더 간결해졌다. 테라폼에서는 정답이 없으므로, 상황에 맞는 코드를 작성하여 사용하면 좋을 것 같다.