Terraform?
IaC 도구로, AWS의 서비스를 코드로서 관리할 수 있게 해주는 플랫폼이다.
특히 AWS의 여러 서비스가 유기적으로 관련되어 있고, 콘솔로 반복적인 작업을 해야할 때 Terraform을 사용한다.
Terraform 모듈을 생성하면서 깨달은 것
- 테라폼에는 생각보다 다양한 문법이 있다. 잘 사용하면, 복잡한 구성도 테라폼으로 설계가 가능하다.
- 모듈을 만들 때는 고려해야 할 부분이 꽤있지만, 잘 만들어놓으면 편하다.
Terraform Module
Terraform 모듈 내에 원하는 리소스들을 구성해놓으면, 여러 다른 위치에서 다른 변수값을 사용해서 리소스를 생성할 수 있다.
모듈은 다음과 같이 사용할 수 있다. 리소스를 구성해놓은 모듈 코드가 있는 PATH를 설정하고, Module이 필요로 하는 변수들을 적어주면 된다.
module "<NAME>" {
source = "<MODULE_PATH>"
cluster_name = "cluster-a"
}
모듈이 생성하는 resource는 다음과 같다. 보통의 리소스를 생성하는 코드와 동일하지만, 모듈을 사용하는 코드에서 건네주는 변수들을 사용해서 리소스를 생성해야 한다. var.cluster_name 과 같이 모듈을 사용하는 곳에서 설정한 변수를 받아와 리소스를 생성할 수 있다.
resource "aws_security_group" "elb-sg" {
name = "${var.cluster_name}-elb-sg"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
이러한 변수를 받아오기 위해서는 모듈에서 variable을 설정해주어야 한다. default 값을 설정할 수도 있고, 비워둬도 된다.
variable "cluster_name" {
default = "cluster_default"
}
모듈에서 리소스를 생성한 후, 생성한 리소스에 대한 정보(arn, id 등)를 받기 위해 모듈에서 output을 통해 리소스 정보를 출력해주어야 한다.
모듈을 사용하는 곳에서는 module.<MODULE_NAME>.elb_sg_name 으로 output을 받아올 수 있다.
output "elb_sg_name" {
value = aws_secruity_group.elb-sg.name
}
Terraform 문법
위의 작업만으로도 테라폼 모듈을 생성하는데 큰 문제는 없지만, 다양한 문법들을 통해 확장성 있는 모듈을 구성할 수 있다.
1. Count
해당 리소스를 몇 개 생성할 것인지 명시해줄 수 있다.
resource "aws_instance" "server" {
count = 4 # create four similar EC2 instances
[CONFIG]
}
}
조금 더 응용해보면, ec2_create_enabled 라는 변수가 true일 때만, 해당 리소스를 생성할 수 있다. (모듈의 확장성을 위해 꼭 필요한 부분이라고 생각한다. 🙆🏻♀️)
count = var.ec2_create_enabled ? 1 : 0
다음과 같이 배열에 생성하고자 하는 정보를 담아서 정보가 다른 동일한 리소스를 여러 개 생성할 수도 있다.
variable "subnet_ids" {
type = list(string)
}
resource "aws_instance" "server" {
# Create one instance for each subnet
count = length(var.subnet_ids)
ami = "ami-a1b2c3d4"
instance_type = "t2.micro"
subnet_id = var.subnet_ids[count.index]
tags = {
Name = "Server ${count.index}"
}
}
2. For-each
for each 구문을 사용해서 map object 기반으로 리소스 생성이 가능하다. each Object의 key, value를 사용해서 설정값들을 기반으로 리소스를 생성할 수 있다.
(set을 기반으로 사용할 때는 each.key만 사용하면 된다.)
firehose_iam_role_policy_objects = {
"kinesis-policy" = {
policy_name = ""
policy = ""
},
"s3-policy" = {
policy_name = ""
policy = ""
}
...
}
resource "aws_iam_role_policy" "firehose_iam_role_policy" {
for_each = var.firehose_iam_role_policy_objects
name = each.value.policy_name
role = aws_iam_role.firehose_iam_role.id
policy = each.value.policy
}
더 많은 문법들이 있겠지만, 이번에 모듈을 생성할 때 가장 중요했던 문법은 count와 for_each 였다. 이를 통해 조금 더 동적으로 테라폼 리소스를 생성할 수 있었다.
복잡한 리소스들을 구성할 때, 최대한 코드를 건드리지 않고 변수 이름, 간단한 구성만을 설정해 리소스를 구성하게 하는 것이 테라폼 모듈을 만들 때 가장 중요한 것 같고 앞으로도 더 노력해야겠다. 🌿
'AWS' 카테고리의 다른 글
[AWS] 대용량 스트림 데이터 처리 플랫폼 - Kinesis (0) | 2021.02.06 |
---|---|
[AWS] 운영 서버 관리 - 코드 배포 (0) | 2020.10.10 |
[AWS] 운영 서버 환경 구성 - 외부 환경 ( 도메인, HTTPS, SSL/TLS ) (0) | 2020.10.09 |
[AWS] 운영 서버 환경 구성 - 다중 서버 ( 오토 스케일링, 로드 밸런서 ) (0) | 2020.10.09 |
[AWS] 운영 서버 환경 구성 - 단일 서버 (0) | 2020.10.07 |