




resource "aws_instance" "appserver" {
ami = var.ami
instance_type = "t2.medium"
tags = {
name = "${var.app_region}-app-server"
}
}
module "primaryapp" {
source = "./modules/appstorage"
app_region = "us-east-2"
ami = "ami-0010d386b82bc06f0"
}
output "subnetid" {
value = aws_instance.appserver.subnet_id
}
나의 VPC를 만든다고 할때

이런식으로 여러개의 모듈을 만든다고 하자.
간단하게 VPC모듈에 선언을 해야하는 것은 main.tf(로직), variables.tf(입력변수), outputs.tf(출력변수) 이다
간단한 VPC를 구성한다고 할때 아래와 같이 구성을 해보자
// VPC 생성
resource "aws_vpc" "this" {
cidr_block = var.vpc_cidr_block
enable_dns_hostnames = true
enable_dns_support = true
}
// Public Subnet 1개 생성
resource "aws_subnet" "public1" {
vpc_id = aws_vpc.this.id
cidr_block = var.public_subnet_cidr_blocks[0]
availability_zone = "ap-northeast-2a"
}
// Private Subnet 1개 생성
resource "aws_subnet" "private1" {
vpc_id = aws_vpc.this.id
cidr_block = var.private_subnet_cidr_blocks[0]
availability_zone = "ap-northeast-2a"
}
// Internet Gateway 생성
resource "aws_internet_gateway" "this" {
vpc_id = aws_vpc.this.id
}
// Public Route Table 생성
resource "aws_route_table" "public" {
vpc_id = aws_vpc.this.id
route {
cidr_block = var.vpc_cidr_block
gateway_id = "local"
}
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.this.id
}
}
// Public Route Table Association
resource "aws_route_table_association" "public_subnet1" {
subnet_id = aws_subnet.public1.id
route_table_id = aws_route_table.public.id
}
resource "aws_route_table_association" "public_subnet2" {
subnet_id = aws_subnet.public2.id
route_table_id = aws_route_table.public.id
}
variable "vpc_cidr_block" {
description = "The CIDR block for the VPC"
type = string
}
variable "public_subnet_cidr_blocks" {
description = "List of CIDR blocks for public subnets"
type = list(string)
}
variable "private_subnet_cidr_blocks" {
description = "List of CIDR blocks for private subnets"
type = list(string)
}
variable "region" {
description = "The AWS region where resources will be created"
type = string
}
다음과 같이 Variables.tf 를 선언함으로써 vpc모듈안에서의 main.tf 에서 var.~~ 으로 접근을 할 수가 있다.
또한 다른 리소스들은 vpc_id를 중요시하기 때문에 필요한 값들을 출력해야한다
output "vpc_id" {
description = "The VPC ID where the RDS instance is deployed"
value = aws_vpc.this.id
}
output "public_subnet_ids" {
description = "A list of subnet IDs for the RDS subnet group"
value = [aws_subnet.public1.id, aws_subnet.public2.id]
}
output "private_subnet_ids" {
description = "A list of subnet IDs for the RDS subnet group"
value = [aws_subnet.private1.id, aws_subnet.private2.id]
}
이런식으로 필요한 값들을 출력하면 된다
이제 이것을 root 모듈에서 선언을 해서 사용을 해보자!
module "vpc" {
source = "./modules/vpc"
vpc_cidr_block = var.vpc_cidr_block
public_subnet_cidr_blocks = var.public_subnet_cidr_blocks
private_subnet_cidr_blocks = var.private_subnet_cidr_blocks
region = var.region
vpc_name = "vpc-name"
public_subnet_names = []
private_subnet_names = []
igw_name = "internet-gateway"
public_route_table_name = "public-route-table"
private_route_table_name = "private-route-table"
}
이러한 방식으로 VPC를 선언해주면 된다!
만약 다른 모듈에서 이 output값을 사용하고 싶다면?
module "ec2" {
source = "./modules/ec2"
vpc_id = module.vpc.vpc_id
public_subnet1_id = module.vpc.public_subnet_ids[0]
}
다음과 같이 module.<MODULE_NAME>.id 와 같이 접근을 해서 가져올 수 있다!
고로 변수 이름을 구분하여 값을 명시적으로 전달을 하였음
제대로 정리해보자
사용 목적
구문
dynamic "block_type" {
for_each = var.some_list
content {
key = each.value.key
value = each.value.value
}
}
예제: Security Group의 ingress 블록
resource "aws_security_group" "example" {
name = "example-sg"
vpc_id = aws_vpc.example.id
dynamic "ingress" {
for_each = var.ingress_rules
content {
from_port = each.value.from_port
to_port = each.value.to_port
protocol = each.value.protocol
cidr_blocks = each.value.cidr_blocks
}
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
동작 설명
사용 목적
구문
resource "resource_type" "resource_name" {
for_each = var.some_map
key = each.key
value = each.value
}
예제: Subnet 생성
resource "aws_subnet" "this" {
for_each = {
public1 = { cidr_block = "10.0.1.0/24", availability_zone = "ap-northeast-2a" }
public2 = { cidr_block = "10.0.2.0/24", availability_zone = "ap-northeast-2c" }
private1 = { cidr_block = "10.0.3.0/24", availability_zone = "ap-northeast-2a" }
private2 = { cidr_block = "10.0.4.0/24", availability_zone = "ap-northeast-2c" }
}
vpc_id = aws_vpc.this.id
cidr_block = each.value.cidr_block
availability_zone = each.value.availability_zone
}
동작 설명
Q1. Dynamic을 언제 사용해야 하나요?
Q2. For_Each를 언제 사용해야 하나요?
Q3. Dynamic과 For_Each를 함께 사용할 수 있나요?
resource "aws_security_group" "this" {
for_each = var.security_groups
dynamic "ingress" {
for_each = each.value.ingress_rules
content {
from_port = each.value.from_port
to_port = each.value.to_port
protocol = each.value.protocol
cidr_blocks = each.value.cidr_blocks
}
}
}
Q4. 값이 없는 경우 처리 방법은?