테라폼을 이용한 리소스 생성 시 몇가지 작업들을 일괄적으로 해주는 방법이 있습니다.
사용자 데이터와 프로비저너를 이용하는 방법인데요 그 둘을 알아보고 차이점에 대해서 설명해 볼까 합니다.
1. 사용자 데이터(user data)
EC2 등의 원격 리소스에서 첫 부팅시 필요한 작업을 하기 위해서 사용됩니다. 부팅이 되면서 필요한 작업들을 일괄적으로 처리해주는 역할입니다.
# main.tf for aws
resource "aws_instance" "webserver" {
ami = "ami-0edab43b6fa892279"
instance_type = "t2.micro"
tags = {
Name = "webserver"
Description = "An Nginx WebServer om Ubuntu"
}
user_data = <<EOF
#!/bin/bash
sudo apt update
sudo apt install nginx -y
systemctl enable nginx
systemctl start nginx
EOF
key_name = aws_key_pair.web.id
vpc_security_group_ids = [ aws_security_group.ssh-access.id ]
}
위와 같이 사용될 수 있으며 resource 안에 자신 만의 블록을 가지고 있습니다. <<EOF와 EOF 사이에 있는 값을 첫 부팅시 실행합니다.
사용자 데이터는 항상 인스턴스 내부에서 실행되며, 실행에 실패해도 인스턴스 생성은 '성공'으로 간주합니다.
사용자 데이터는 EC2 인스턴스와 같이 "특정 리소스"에서만 사용이 가능합니다.
코드에 대한 설명을 하면, aws_instance는 2개의 인자가 필수적으로 필요한데 ami, instance_type입니다. region 또한 필요한데
# provider.tf
provider "aws" {
region = "us-west-1"
}
같은 구성 파일에 있는 provider.tf를 생성해서 region을 지정해주면 terraform이 알아서 region을 파악합니다.
tags는 선택 사항인데 없어도 문제는 없다고 합니다.
그리고 원격으로 실행되는 코드인 만큼 네트워크로 연결이 되어 있어야 하는데 연결되기 위해선 연결정보를 가지고 있어야 합니다. 그래서 key_name과 vpc_security_group_ids를 통해 그 값들을 받아오고 아래와 같은 리소스들을 통해 그 정보를 작성할 수 있습니다.
resource "aws_key_pair" "web" {
public_key = file("/root/.ssh/web.pub")
}
resource "aws_security_group" "ssh-access" {
name = "ssh-access"
description = "Allow SSH access from the Internet"
ingress = {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
VPC에 있는 보안 그룹과의 설정까지 끝마쳤다면, terraform apply를 실행해 EC2 인스턴스에 SSH를 통해 접속할 수 있습니다.
2. 프로비저너(provisioner)
리소스 생성 후 추가적인 작업을 수행하기 위한 기능, 주로 리소스 생성 직후에 초기 설정이나 소프트웨어 설치 등의 작업을 자동화하는데 사용됩니다.
가장 유명한 프로비저너 유형에는 local-exec랑 remote-exec가 있습니다. 프로비저너는 리소스 내에서 정의되는 특별한 블록이며 이름이 필요하지 않습니다.
프로비저너는 사용자 데이터와 다르게 EC2 인스턴스 이외의 다양한 리소스 유형에서도 사용가능한 장점이 있습니다.
사용자 데이터와 다르게 프로비저너는 리소스 재생성 시미다 실행됩니다. local_exec는 테라폼이 실행되는 머신에서, remote-exec는 생성된 리소스에서 실행됩니다.
provisioner "local-exec" {
command = "echo Instance ${aws_instance.webserver.public_ip} Created! > /tmp/instance_state.txt"
}
이 코드에서는 인스턴스가 생성된 후 로컬 컴퓨터의 /tmp/instance_state.txt 파일에 인스턴스의 공용 IP 주소와 함께 “Created!“라는 메시지를 기록합니다.
provisioner "remote-exec" {
inline = [
"sudo apt update",
"sudo apt install nginx -y"
]
}
remote-exec: 원격 머신(ex. EC2 인스턴스)에서 명령어를 실행합니다. terraform이 배포한 원격 리소스에서 SSH 또는 WinRM을 통해 명령어를 실행합니다. 원격 서버에서 특정 소프트웨어를 설치하거나, 구성 작업을 수행할 때 사용합니다.
사용자 데이터와 다르게 프로비저너는 실행 실패 시 리소스 생성이 실패한 것으로 간주되며, 테라폼은 해당 리소스를 파괴하려고 시도합니다. 그래서 terraform apply를 실행하면 프로비저너를 다시 실행합니다.
(terraform apply 명령어는 리소스가 없는 처음에는 리소스를 생성하고, 두 번째 부터 변경 사항이 있는 경우에는 업데이트만 진행합니다)
계속해서 실패할 경우를 대비하여 on_failure 설정을 제공하는데 on_failure = continue로 설정하면, 프로비저너 실패 시에도 테라폼은 리소스를 파괴하지 않고 계속 진행합니다.
on_failure = fail로 설정하면 실패 시 실행할 명령어를 지정할 수 있습니다
resource "aws_instance" "webserver" {
ami = "ami-0edab43b6fa892279"
instance_type = "t2.micro"
provisioner "local_exec" {
on_failure = fail # 실패 시 실패 메세지 작성
command = "echo Instance ${aws_instance.webserver.public_ip} Created! > /tmp/instance_state.txt"
}
provisioner "local-exec" {
when = destroy
command = "echo Instance ${aws_instance.webserver.public_ip} Destroyed! > /tmp/instance_state.txt"
}
}
local_exec에서 when = destroy로 설정해 놓으면 리소스를 파괴할 때 아래에 ccommand를 실행하라는 의미입니다.
프로비저너 코드
resource "aws_instance" "webserver" {
ami = "ami-0edab43b6fa892279"
instance_type = "t2.micro"
provisioner "remote-exec" {
inline = [
"sudo apt update",
"sudo apt install nginx -y",
"systemctl enable nginx",
"systemctl start nginx"
]
}
connection {
type = "ssh"
host = self.public_ip
user = "ubuntu"
private_key = file("/root/.ssh/web")
}
key_name = aws_key_pair.web.id
vpc_security_group_ids = [ aws_security_group.ssh-access.id ]
}
remote-exec에서 inline 안에 원하는 명령어들을 넣을 수 있는데, inline 리스트의 명령들은 배포된 후에 원격 인스턴스에서 실행됩니다.
remote instance(EC2)에 연결하기 위해선 리눅스 인스턴스라면 SSH연결을 해야하고 윈도우라면 WinRM연결이 되어있어야 합니다.
사용자 데이터와는 다르게 connection 블록을 넣어주어 설정을 처리할 수 있습니다.
'[Cloud] > [Terraform]' 카테고리의 다른 글
[Terraform] S3에서 상태 파일 업로드, 상태 파일 관리 명령어 (0) | 2024.08.09 |
---|---|
[Terraform] 테라폼으로 AWS DynamoDB 생성, 업로드(GSI) (0) | 2024.08.08 |
[Terraform] 테라폼 라이프 사이클(create_before_destroy, prevent_destroy) (1) | 2024.08.06 |
[Terraform] 리소스 참조(암묵적 참조, 명시적 참조) (0) | 2024.08.05 |
[Terraform] 테라폼 변수 타입 종류 (0) | 2024.08.05 |