IaC - Terraform
6 minute read
Terraform 이론과 사용법
코드형 인프라란?
- 인프라의 구축, 관리, 프로비저닝을 코드로 관리하는 방법론
- 프로비저닝, 시스템 변경, 구성 등 반복되는 과정을 코드를 통해 자동화하여 일관성있게 구성/변경
- 인프라 형상을 정의한 source code가 있다면 언제든지 동일한 인프라를 전개할 수 있다.
- 인프라 형상을 코드화하였기 때문에 git으로 버전관리가 가능하다.
Idempotent Code
- 코드로 관리하기 때문에 항상 같은 전개를 할 수 있다.
- 코드로 관리하기 때문에, 테라폼 환경을 벗어난 리소스에 대한 핸들링은 피해야 한다.
Terraform 사용법
terraform init
- 지정한 backend에 상태 저장을 위한
.tfstate
파일을 생성 - init 작읍을 완료하면, local에는
.tfstate
에 정의된 내용을 담은.terraform
파일이 생성됨 - 기존에 다른 개발자가 이미
.tfstate
에 인프라를 정의했다면, 다른 개발자는 init을 통해 local에서 sync를 맞출 수 있다.
- 지정한 backend에 상태 저장을 위한
terraform plan
- Public Cloud에 적용하기 전에 Terrarom Code의 문법을 확인하는 명령어
+
: 새로 생성-
: 삭제~
: 교체/변경
terraform apply
- 문법 검사 결과를 배포하는 명령어
terraform destroy
- 이미 배포된 IaC Infra를 제거하는 명령어
AWS VPC
variable "변수명" {
type = string or list or map
description = "설명"
default = [
value
]
]
AWS Provider
Provider를 사용하여 어떤 Infra 자원을 사용할 것인지 선택할 수 있다.
provider "aws" {
region = var.region변수
access_key = var.access_key변수
secret_key = var.secret_key변수
}
terraform {
required_provider {
aws = {
source = "hashicorp/aws"
version = "버전명"
}
}
}
VPC
resource "aws_vpc" "변수명" {
cidr_block = "CIDR"
tags = {
Name = "VPC 이름"
}
}
ex)
resource "aws_vpc" "kr-front-vpc" {
cidr_block = "10.101.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "Zen Front VPC(10.101.0.0/16)"
}
}
Subnet
resource "aws_subnet" "서브넷 변수명" {
cidr_block = "서버넷 CIDR 범위"
vpc_id = aws_vpc.서브넷 변수명.id
availability_zone = "가용성존"
tags = {
Name = "서브넷 Name"
}
}
Internet Gateway
resource "aws_internet_gateway" "InternetGateway변수명" {
vpc_id = aws_vpc.VPC변수명.id
tags = {
Name = "InternetGateway명"
}
}
Route Table
resource "aws_route_table" "RouteTable변수명" {
vpc_id = aws_vpc.VPC변수명.id
route {
cidr_block = "CIDR값"
gateway_id = aws_internet_gateway.InternetGateway변수명.id
}
tags = {
Name = "RouteTable명"
}
}
resource "aws_route_table_association" "RT변수" {
subnet_id = aws_subnet.서브넷변수명.id
route_table_id = aws.route_table.RT명.id
}
NAT Gateway
resource "aws_eip" "EIP 변수명" {
vpc = true
tags = {
Name = "EIP명"
}
}
resource "aws_nat_gateway" "NAT gateway변수" {
allocation_id = aws_eip.EIP변수명.id
subnet_id = aws_subnet.Sunet변수명.id
depends_on = ["aws_internet_gateway.InternetGateway변수명"]
tags = {
Name = "NAT Gateway명"
}
}
Security Group
resource "aws_security_group" "SG변수" {
vpc_id = aws_vpc.VPC변수명.id
name = "SG이름"
description = "SG 요약"
ingress {
description = "주석"
from_port = 포트 번호 범위
to_port = 포트 번호 범위
protocol = "프로토콜 타입"
cidr_blocks = ["CIDR"]
}
engress {
from_port = 포트 번호 범위
to_port = 포트 번호 범위
protocol = "프로토콜 타입"
cidr_blocks = ["CIDR"]
}
tags = {
Name = "SG Tag"
}
}
NACL
resource "aws_network_acl" "NACL변수" {
vpc_id = aws_vpc.VPC변수명.id
ingress {
protocol = "-1"
rule_no = 100
action = "allow"
cidr_block = "0.0.0.0/0"
from_port = 0
to_port = 0
}
engress {
protocol = "-1"
rule_no = 100
action = "allow"
cidr_block = "0.0.0.0/0"
from_port = 0
to_port = 0
}
tags = {
Name = "NACL Tag"
}
}
resource "aws_network_acl_association" "NACL명" {
network_acl_id = aws_network_acl.NACL변수명.id
subnet_id = aws_subnet.서브넷변수명.id
}
VPC Peering
resource "aws_vpc_peering_connection" "VP변수" {
vpc_id = aws_vpc.VPC변수명.id
peer_vpc_id = aws_vpc.Peering할 VPC변수명.id
auto_accept = true
tags = {
Name = "Peering 명"
}
}
EC2
resource "aws_instance" "인스턴스 변수" {
ami = "원하는 AMI"
instance_type = var.인스턴스 타입 변수
key_name = var.PEM KEY 변수
subnet_id = aws_subnet.전개할 subnet.id
vpc_security_group_ids = aws_security_group.SG변수명.id
root_block_device {
volume_size = "EBS 용량"
volume_type = "EBS 타입"
delete_on_termination = true # EC2 종료시 EBS 볼륨 삭제
}
tags = {
Name = "EC2 인스턴스명"
}
}
ALB
resource "aws_alb" "ALB변수" {
name = "ALB명"
idle_timeout = value # web server timeout
load_balancer_type = "LB type"
security_group = [aws_security_group.SG변수명.id]
subnets = [aws_subnet.Subnet변수명.id]
enable_deletion_protection = true # 삭제보호 활성화/비활성화
tags = {
Name = "ALB 명"
}
}
resource "aws_lb_listener" "리스터 변수" {
load_balancer_arn = aws_alb.ALBGroup변수.arn
port = 리스터 포트
protocol = "리스너 프로토콜 type"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.ALB TargetGroup 변수.arn
}
}
resource "aws_lb_target_group" "ALB TargetGroup변수" {
name = "ALB Target Group명"
port = 포트번호
protocol = "프로토콜 type"
vpc_id = aws_vpc.VPC변수.id
tags = {
Name = "ALB TargetGroup명"
}
}
resource "aws_lb_target_group_attachment" "TG연결변수" {
target_group_arn = aws_lb_target_group.ALBGroup변수.arn
target_id = aws_instance.인스턴스 변수.id
}
S3
# 생성
resource "aws_s3_bucket" "버킷변수" {
bucket = "버킷명"
lifecycle {
prevent_destroy = false
}
}
# Access 제한
resource "aws_s3_bucket_public_access_block" "Public Access 제한변수" {
bucket = "aws_s3_bucket.버킷변수.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
# public Access 제한
resource "aws_s3_access_point" "Access Point 변수" {
name = "Access Point 이름"
bucket = "버킷명"
# 특정 VPC에서만 연결 설정
vpc_configuration {
vpc_id = aws_vpc.VPC변수.id
}
}
EFS
# 리소스 생성
resource "aws_efs_file_system" "EFS 변수" {
availability_zone_name = 가용성존 이름
creation_token = "토큰이름"
encrypted = true # 암호화 활성화 여부
# kms_key_id = "암호화 키파일"
performance_mode = 성능모드 선택(기본 Bust Mode)
throughput_mode = throughput 모드 선택("provisioued")
# provisioned_throughput_in_mibps =
tags = {
Name = "EFS 이름"
}
}
# 리소스 연결
resource "aws_efs_mount_target" "마운트 타겟 변수" {
file_system_id = aws_efs_file_system.EFS변수.id
subnet_id = var.서브넷ID변수
security_group = [
aws_security_group.SG변수.id
]
}
RDS
resource "aws_db_subnet_group" "SG변수명" {
name = "SubnetGroup 명"
subnet_ids = [aws_subnet.DB SG변수.id]
tags = {
Name = "DB SubnetGroup 명"
}
}
Aurora Mysql Serverless
resource "aws_rds_cluster_instance" "DB인스턴스변수" {
count = 총 생성할 인스턴스 수
identifier = "인스턴스명"
engine = DB 엔진
engine_version = DB 엔진 버전
cluster_identifier = aws_rds_cluster.RDS클러스터변수.cluster_identifier
instance_class = "DB 인스턴스 타입"
db_subnet_group_name = aws_db_subnet_group.DB서브넷그룹변수.id
db_parameter_group_name = aws_db_parameter_group.DB파라미터변수.id
publicly_accessible = false
}
resource "aws_rds_cluster" "Mysql Server Cluster변수" {
cluster_identifier = "클러스터 식별자 정의"
engine = "DB 엔진명"
engine_mode = "serverless" # 중요
engine_version = "DB 엔진 버전"
availability_zone = ["가용성존"]
database_name = "DB 이름 정의"
master_username = DB 마스터 계정
master_password = DB 마스터 패스워드
port = "포트"
db_subnet_group_name = aws_db_subnet_group.DB서브넷그룹변수.id
vpc_security_group_ids = [aws_security_group.DB보안그룹변수.id]
db_cluster_parameter_group_name = aws_rds_cluster_parameter_group.DB클러스터 파라미터그룹.id
backup_retention_period = 백업기간
preferred_backup_window = "백업시간"
storage_encryted = true # 스토리지 활성화 여부
final_snapshot_identifier = "DB 스냅샷 이름"
skip_final_snapshot = false
lifecycle {
create_before_destroy = true
}
}
Document DB
# AWS Cloud Tail 감시로그 활성화
parameter {
name = "audit_logs"
value = "enabled"
}
# 변경 스트림 로그 유지, 사용기간
parameter {
name = "change_stream_log_retention_duration"
value = "3600"
}
# 느린 작업 프로파일링
parameter {
name = "profiler"
value = "enabled"
}
# 샘플링 작업속도
parameter {
name = "profile_sampling_rate"
value = "0.1"
}
parameter {
name = "profiler_threshold_ms"
value = "120"
}
MemoryDB for Redis
# 샤드, 리플리카 갯수
num_shards = 2
num_replicas_per_shard = 2
# 전송중 암호화
tls_enabled = true
- terraform docs
- thanks to 신선호
I feedback.
Let me know what you think of this article in the comment section below!
Let me know what you think of this article in the comment section below!
comments powered by Disqus