Terraform의 기본 용어 및 개념
- Provider
- Resource
- Variables
- Locals
- State
- Output
- Provisioner
- Module
- Data
🔍개념 설명에 앞서.. (Terraform 폴더 구조)
Terraform은 일반적으로 아래와 같은 폴더 구조로 된다. (각 파일이 무슨 역할인지는 아직 몰라도 된다.)
😐 기본 구조 (minimal)
Terraform_folder/
├── README.md
├── main.tf
├── variables.tf
├── outputs.tf
😀 기본 구조 (maximal)
Terraform_folder/
├── README.md
├── main.tf
├── variables.tf
├── outputs.tf
├── modules/
| ├── main.tf
| ├── variables.tf
| ├── outputs.tf
Terraform의 명령어를 실행하면 실행한 위치의 모든 tf 파일을 읽어서 실행한다.
⚙ 개발 환경별 폴더 나누기
각 환경을 나눠줌으로써 각각 환경에 맞게 실행 가능.
또한 각 폴더마다 .tfstate
파일을 따로 생성함으로써 꼬임을 방지할 수 있다.
├── dev/
│ ├── main.tf
│ ├── variables.tf
├── stage/
│ ├── main.tf
│ ├── variables.tf
└── prod/
├── main.tf
└── variables.tf
Provider (프로바이더)
- 테라폼으로 생성할 인프라의 종류를 의미한다. (ex. AWS, Azure, GCP, ..etc)
- 일반적으로
provider.tf
파일에 정의한다.
✍ HCL Syntax
provider "<provider>" {
attribute1 = value1
}
예시 1) AWS
AWS 에 접근하기 위한 access_key와 secret_key 인증 정보를 제공
# AWS를 provider로 지정
provider "aws" {
region = "us-east-1"
access_key = "your-access-key"
secret_key = "your-secret-key"
}
예시 2) Azure
provider "azurerm" {
features = {}
}
Resource (리소스)
- 리소스(Resource)는 쉽게 클라우드의 서비스에 해당된다. (ex. AWS - EC2, S3, RDS, Lambda, IAM, VPC ..etc)
- 일반적으로
main.tf
파일에 정의한다.
✍ HCL Syntax
resource "<provider>_<resource_type>" "<resource_name>" { # resource_name은 사용자가 임의로 지정할 수 있다
attribute1 = value1 # 속성과 설정
}
예시 1) EC2 Instance
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "example-instance"
}
}
예시 2) VPC
resource "aws_vpc" "example" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
}
Variables (베리어블, 변수)
variables은 쉽게 인프라에 사용되는 변수의 값을 선언하고 할당하는 데 사용되는 기능이다.
→ 즉 인프라의 변수는 variables 여기에 저장하면 된다.
사용 예시)
만약 개발하는 어플리케이션 이름이 "구글"이라면, 이름을 variables에 저장한다. 개발 도중에 이름을 호출 해야 할 때 마다 variables에서 불러오면 된다.
👓 특징
- 변수를 variables에 관리 함으로써 변수를 다른 환경에서 재사용 가능하게 만들며, 이해하기 쉽게 만든다.
- 결과적으로 인프라 구성을 유연하게 만든다
- 변수를 variables에 관리 함으로써 인프라 구성의 민감한 정보를 보호할 수 있다.
- 일반적으로
variables.tf
파일에 적는다.
✍ HCL Syntax
variable <name> {
description = <value>
type = <value>
default = <value>
}
var.<name>
😎 사용 예시 1)
my_value 라는 변수를 variables에 저장
variable "my_value" {
type = string
}
AWS EC2 인스턴스 만들 때 variables에 저장된 my_value 사용하여의 이름을 설정하기.
resource "aws_instance" "example" {
name = var.my_value
}
😎 사용 예시 2)
variable "ami" {
description = "The AMI for the instance"
type = string
}
variable "instance_type" {
description = "The instance type for the instance"
type = string
}
resource "aws_instance" "my_instance" {
ami = var.ami
instance_type = var.instance_type
}
Locals (로컬)
locals는 기본적으로 variables와 비슷하다. 둘다 Terraform에서 값을 저장하는 데 사용되는 변수이다.
하지만 당연히 차이점이 있다! (아래에 적어 놓았다)
✍ HCL Syntax
locals {
name = "my-instance"
}
😎 사용 예시)
locals {
name = "my-instance"
region = "us-east-1"
}
resource "aws_instance" "my_instance" {
ami = "ami-12345678"
instance_type = "t2.micro"
tags {
Name = local.name
Region = local.region
}
}
📌 Tags)
tags블록은 리소스를 식별하고 분류하는 데 사용할 수 있는 key-value 쌍이다.
인터넷에 검색하면 사용하는 이유를 알 수 있다.
variables 와 locals 의 차이
- variable : 모듈 간에 전달되는 입력 값으로 더 큰 범위에서 사용된다.
- 외부에서 값이 변경될 수 있다.
- 모듈 안에서는 var.tags, var.environment 같은 형식으로 사용한다.
- locals : 특정 모듈 또는 블록 내에서만 사용되므로 범위가 제한된다. (마치 지역변수같은 느낌)
- 특정 모듈 또는 블록 내에서 정의되어 있으므로 외부에서 변경되지 않는다.
특징 |
variables | locals |
참조 범위 | Terraform 구성의 어디에서나 참조 가능 | 해당 모듈에서만 참조 가능 |
값 변경 | Terraform 구성의 실행 중에 값을 변경 가능 | Terraform 구성의 실행 중에 값을 변경 불가능 |
사용 사례 | 일반적으로 외부에서 제공되는 값을 저장하는 데 사용 | 일반적으로 중간 값을 저장하거나 코드를 더 읽기 쉽게 만드는 데 사용 |
예시 | - AWS region - VPC ID - Subnet ID, - ...etc |
- S3 bucket name - EC2 instance tags - Lambda environment variables - ...etc |
📋결론 | 인프라 서비스의 공통적인 부분의 값은 variables를 사용하면 된다. | 서비스의 세부적인 값은 locals 사용하면된다. |
😎 사용 예시1) variables : AWS region
variable "aws_region" {
type = string
default = "us-east-1"
}
😎 사용 예시2) locals : S3 bucket name
locals {
s3_bucket_name = "my-s3-bucket-${var.aws_region}"
}
State (스테이트, 상태)
State는 Terraform이 생성한 인프라의 현재 상태를 기록하는 파일이다.
- State는 Terraform이 어떤 리소스를 생성하고 어떤 속성을 가지고 있는지를 추적하는 데 사용된다.
- State 파일이 없으면 인프라의 현재 상태를 확인할 수 없게 된다.
- Terraform 명령어를 실행할 때마다 자동으로 state 파일이 업데이트된다.
- 일반적으로
.tfstate
파일 형태로 저장된다. - State 파일은 일반적으로 다음과 같은 로컬이나 원격 저장소에 저장한다.
- 로컬 디렉토리
- Amazon S3 bucket
- Google Cloud Storage bucket
- ...etc
- State 파일은 JSON 형식으로 작성되며 다음과 같은 정보를 포함한다.
- 리소스 이름
- 리소스 유형
- 리소스 속성
- 리소스 상태
😎 사용 예시) AWS EC2 인스턴스를 생성하는 Terraform 구성
{
"version": 4,
"terraform_version": "1.0.2",
"serial": 5,
"lineage": "abc12345-defg-6789-hijk-lmnopqrstuvwx",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "aws_instance",
"name": "example_instance",
"provider": "provider.aws",
"instances": [
{
"index_key": "",
"schema_version": 2,
"attributes": {
"ami": "ami-0c55b159cbfafe1f0",
"instance_type": "t2.micro",
"tags": {
"Name": "example-instance"
}
},
"private": "",
"dependencies": []
}
]
}
]
}
Outputs (아웃풋, 출력)
Output은 Terraform 코드 실행으로 생성한 인프라의 속성이나 특정 값을 추출하거나 표시하고자 할 때 사용한다.
즉, 사용자가 Terraform을 적용한 후 결과값을 확인하고 싶을 때 사용하는 변수이다.
terraform apply
될 때 콘솔에 출력해 준다. 혹은terraform output
으로 콘솔에서 확인할 수 있다.
$ terraform apply
...(생략)
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
vpc_id = "vpc-004c2d1ba7394b3d6"
- Output을 사용하여 리소스의 특정 속성이나 값을 외부에서 활용할 수 있게 된다.
- 다른 Terraform 코드나 외부 툴, 스크립트에서 사용할 수 있다.
- Ex.) EC2의 IP 주소는 자동 생성되는데, 만약 개발중에 IP 주소가 필요하면 output을 활용하면 된다.
- 일반적으로
outputs.tf
파일에 저장한다. - 명령어를 통해 터미널에 쉽게 출력할 수 있다. → 🐛디버깅에 유리!
terraform output <target>
✍ HCL Syntax
output <output_name> {
value = <value>
}
😎 사용 예시) AWS EC2 인스턴스의 퍼블릭 IP 주소를 output으로 정의
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
output "public_ip" {
value = aws_instance.example.public_ip
}
output 명령어를 통해 확인
$ terraform output
public_ip = 11.234.22.394
Provisioner (프로비저너)
테라폼에서 프로비저닝이란 인프라를 생성 후, 추가 작업을 실행하는 기능을 나타낸다.
- 가상 서버를 만들 때, 서버에 필요한 소프트웨어나 설정을 설치하고 설정할 수 있다.
- 이는 새로운 시스템을 구축할 때 필요한 일련의 작업을 자동화할 수 있다.
- 개발자는 더 쉽게 인프라를 구성하고 유지보수할 수 있게 된다.
- 일반적으로
resource
안에 적는다.
✍ HCL Syntax)
resource "aws_instance" "example" {
provisioner "local-exec" {
command = "echo 'Hello, world!'"
}
}
😎 예시) AWS의 인스턴스를 생성하고 인스턴스에 Nginx 웹 서버를 설치하기
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0" # 이미지 ID (운영체제 등이 들어있는 이미지)
instance_type = "t2.micro" # 인스턴스 유형
provisioner "remote-exec" {
inline = [
"sudo apt-get update", # 패키지 업데이트
"sudo apt-get install -y nginx", # Nginx 웹 서버 설치
"sudo service nginx start", # Nginx 시작
]
}
}
Module (모듈)
Module이란 아주 쉽다.
그냥 목적에 따라 Terraform 파일을 그룹으로 나누는 방법이다.
Module은 하나의 기능을 수행하도록 설계된 리소스 집합이다.
👓 특징
- 코드를 조직화하고 가독성과 유지 관리성을 향상시킨다.
- 코드의 재사용성을 향상시킨다
- 모듈은 다른 모듈을 호출하여 구성을 구성할 수 있습니다.
✍ HCL Syntax
module "<name>" {
source = <source_path>
}
😎 사용 예시)
AWS로 클라우드를 만든다면 VPC, EC2와 같은 모듈을 만들 수 있다.
modules 디렉토리 아래에 VPC 와 EC2 디렉토리가 있다.
/terraform
├── main.tf
├── variables.tf
├── outputs.tf
├── modules
│ ├── vpc
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── ec2
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
└── provider.tf
VPC 모듈 (modules/vpc/main.tf):
# modules/vpc/main.tf
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "main-vpc"
}
}
EC2 모듈 (modules/ec2/main.tf):
# modules/ec2/main.tf
resource "aws_instance" "example" {
ami = var.ami_id
instance_type = var.instance_type
subnet_id = var.subnet_id
tags = {
Name = "example-instance"
}
}
메인 Terraform 파일 (main.tf):
# main.tf
provider "aws" {
region = "us-west-2"
}
module "vpc" {
source = "./modules/vpc"
vpc_cidr = "10.0.0.0/16"
}
module "ec2" {
source = "./modules/ec2"
ami_id = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
subnet_id = module.vpc.subnet_ids[0]
}
Data Source (데이터)
Data 블록은 기존의 인프라 리소스나 데이터(외부에서 정의된 정보)를 가져올 때 사용되는 블록이다.
이 블록을 사용하여 기존 인프라 리소스를 읽고 이를 Terraform 코드 내에서 사용할 수 있다.
Data 블록은 주로 기존의 인프라에 있는 정보를 활용해 새로 무언가를 하고싶을 때 활용된다.
여기서 외부에서 정의된 정보란??
→→→ Terraform 코드가 실행되는 시점에서 이미 존재하는 인프라의 정보.
- Ex) AWS Console로 만든 AWS 서비스
- Ex) 내가 만든 AWS 서비스가 아니라 나의 관리밖에서 다른 사람이 만든 AWS 서비스
✍ HCL Syntax
data <external_data_source_type> <data_block_name> {
# 데이터 블록 설정 및 속성
}
👓 구성 요소
- <external_data_source_type>: 각 공급자의 데이터 유형을 지정.
- <data_block_name>: 데이터 블록의 이름을 지정.
😎 사용 예시) AWS에서 특정 VPC의 정보를 가져오는 data 블록
data "aws_vpcs" "my_vpc" {
tags = {
Name = "my-vpc"
}
}
output "vpc_id" {
value = data.aws_vpcs.my_vpc.ids[0]
}
'Terraform' 카테고리의 다른 글
terraform fmt란? (0) | 2024.04.22 |
---|---|
[Terraform] terraform.lock.hcl 파일이란 (.terraform 파일) (1) | 2024.03.19 |
[Terraform] variables.tf 파일과 *.tfvars 파일 차이는? (0) | 2024.03.15 |
[Terraform] 테라폼의 "Backend"란? (tfstate 상태 파일을 저장하는 곳) (0) | 2024.03.11 |
[Terraform #01] 테라폼 쉽게 개념 정리 & 설명 (테라폼 기본 명령어, IaC, Infrastructure as Code) (1) | 2023.12.17 |