# 0. 목적
- 테라폼의 Variable 모듈을 사용하여 어떤 식으로 변수화를 진행할 수 있을지를 확인하고, 확장을 해본다.
- Official AWS Provider를 사용하여 VPC & Public Subnet & Private Subnet을 순차적으로 올려보고, 변수화를 진행한다.
- 확장 가능성을 확인해본다.
- 여러개를 한번에 프로비저닝해본다.
- 코드 위주로 작성한다.
진행 환경
- MacOS M1
- terraform version: v1.5.7
- aws provider: 5.17.0
- AWS: 2.13.21
- Python: 3.11.5
- aws configure 미리 설정 후 진행(Access & Secret Key)
# 1. Variable 선언
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.17.0"
}
}
}
variable "user_title" {
type = string
default = "cw2"
}
resource "aws_vpc" "vpc" {
cidr_block = "10.10.0.0/16"
enable_dns_hostnames = true
tags = {
Name = "${var.user_title}-vpc"
Terraform = "true"
Environment = "dev"
}
}
resource "aws_subnet" "public_sn1" {
vpc_id = aws_vpc.vpc.id
cidr_block = "10.10.10.0/24"
availability_zone = "ap-northeast-1a"
map_public_ip_on_launch = true
tags = {
Name = "${var.user_title}-public-sn"
}
}
resource "aws_subnet" "private_sn1" {
vpc_id = aws_vpc.vpc.id
cidr_block = "10.10.11.0/24"
availability_zone = "ap-northeast-1a"
map_public_ip_on_launch = false
tags = {
Name = "${var.user_title}-private-sn1"
}
}
위의 테라폼 코드를 통해서 cw2-vpc, cw2-public-sn, cw2-private-sn1 서브넷이 프로비저닝 된다.
"user_title"을 통해서 테라폼 변수를 선언하고, default 값으로 cw2 설정했다. 변수 타입은 문자열이므로 string.
이를 사용하기 위해서 terraform apply를 실행하면, 변수의 값은 default이 사용된다.
# 2. 사용법
단순히 기본 값으로 쓸거면, 변수화를 진행할 이유가 없다.
변수를 받아 동적으로 프로비저닝을 하기 위해선, terraform apply 시 아래와 같은 태그를 붙여 변수의 값을 지정할 수 있다.
terraform apply -var="[정의된 변수]=[사용자 입력 값]"
이를 적용해본 결과는 아래와 같다.
kakao란 변수로 user_title 값을 설정했으므로 해당 부분이 적용되어 프로비저닝 되었음을 확인할 수 있다.
# 3. 활용하기
위의 사용법에서 조금 더 나아가 다른 부분까지 변수화를 진행해보자. 예를 들어, 서브넷의 가용 영역도 별도로 받고, VPC의 Network 영역을 받아서 Subnet에도 적용을 시켜본다.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.17.0"
}
}
}
variable "user-title" {
type = string
default = "cw2"
}
variable "vpc-cidr" {
type = string
default = "10.10.0.0/16"
}
variable "subnet-az" {
type = string
default = "a"
}
resource "aws_vpc" "vpc" {
cidr_block = var.vpc-cidr
enable_dns_hostnames = true
tags = {
Name = "${var.user-title}-vpc"
Terraform = "true"
Environment = "dev"
}
}
resource "aws_subnet" "public_sn1" {
vpc_id = aws_vpc.vpc.id
cidr_block = "${substr(var.vpc-cidr, 0, 5)}.10.0/24"
availability_zone = "ap-northeast-1${var.subnet-az}"
map_public_ip_on_launch = true
tags = {
Name = "${var.user-title}-public-sn1"
}
}
resource "aws_subnet" "private_sn1" {
vpc_id = aws_vpc.vpc.id
cidr_block = "${substr(var.vpc-cidr, 0, 5)}.11.0/24"
availability_zone = "ap-northeast-1${var.subnet-az}"
map_public_ip_on_launch = false
tags = {
Name = "${var.user-title}-private-sn1"
}
}
이번에는 총 3개의 변수를 사용했다. user-title, vpc-cidr, subnet-az
그리고 해당 변수들을 필요한 부분에 적용시켰고, subnet의 cidr_block의 경우는 테라폼 자체 함수를 통해서 문자열을 잘라 넣어서 네트워크 영역을 나눠 사용했다.
변수를 동적으로 적용하는 법은 아래와 같다.
terraform apply --auto-approve -var="user-title=test" \
-var="vpc-cidr=10.10.0.0/16" -var="subnet-az=d"
이번에는 test라는 공통된 이름을 사용했고 cidr 및 Subnet의 가용 영역 또한 동적으로 설정했다.
# 4. 파일을 통해 변수 관리
테라폼에서는 파일을 통해 변수를 관리 및 사용하는 것이 가능하다.
terraform은 `.tfvars` 확장자 파일로 변수 값을 정의해놓을 수 있다.
즉, 코드를 다 짜놓으면 이 부분만 건드려서 프로비저닝 하는 것이 가능하다.
아래의 `terraform.tfvars`을 정의하고 이전에 사용했던 테라폼 코드를 동작시켜본다.
user-title = "s"
vpc-cidr = "10.11.0.0/16"
subnet-az = "c"
`terraform apply -var-file="terraform.tfvars"
# 5. 환경변수로 테라폼 변수 사용
테라폼에서는 환경변수를 통해 변수를 입력받을 수 있다.
이를 위해선 'TF_VAR_' 접두사를 붙여서 환경변수를 선언해야 한다.
Linux & MacOS의 경우 `export TF_VAR_example_var="사용자_지정_값"` 으로 환경변수 선언이 가능하다.
간단하게 사용 가능하다.
# 6. 한번에 여러 개 프로비저닝하기
테라폼과 aws Provider에서 이를 위해서 count 또는 for_each 를 사용할 수 있다. with variable
1. count 사용
variable "subnet_count" {
type = number
default = 3
}
resource "aws_subnet" "example_subnet" {
count = var.subnet_count
vpc_id = aws_vpc.nba-vpc.id
cidr_block = "10.10.${count.index}.0/24"
}
-> main.tf
이렇게 subnet_count 변수의 값을 통해서 그 개수만큼의 서브넷을 생성할 수 있다. VPC의 CIDR이 10.10.*.*/16은 된다는 가정
이렇게 프로비저닝을 하면, subnet-0(10.10.0.0/24), subnet-1(10.10.1.0/24), subnet-2(10.10.2.0/24) 서브넷이 만들어진다.
2. for_each 사용
subnets = {
subnet1 = {
cidr_block = "10.10.1.0/24"
name = "Subnet 1"
}
subnet2 = {
cidr_block = "10.10.2.0/24"
name = "Subnet 2"
}
subnet3 = {
cidr_block = "10.10.3.0/24"
name = "Subnet 3"
}
}
-> terraform.tfvars
resource "aws_subnet" "example_subnet" {
for_each = var.subnets
vpc_id = aws_vpc.nba-vpc.id
cidr_block = each.value.cidr_block
tags = {
Name = each.value.name
}
}
-> main.tf
이렇게 사용하면 각각 subnet-1(10.10.1.0/24), subnet-2(10.10.2.0/24), subnet-23(10.10.3.0/24)으로 서브넷 3개가 생성된다.
3. EC2 + for_each
variable "ec2_instances" {
type = map(object({
instance_type = string
ami = string
}))
default = {
instance1 = {
instance_type = "t2.micro"
ami = "ami-0123456789abcdef0"
}
instance2 = {
instance_type = "t2.small"
ami = "ami-0123456789abcdef1"
}
instance3 = {
instance_type = "t2.medium"
ami = "ami-0123456789abcdef2"
}
}
}
resource "aws_instance" "example_instance" {
for_each = var.ec2_instances
ami = each.value.ami
instance_type = each.value.instance_type
}
이렇게 EC2를 띄울 때도 변수를 적용할 수 있다.